DEVICE ZXSPECTRUM128
include "../_sdk/sys_h.asm"
;title TURBO PASCAL Compiler for CP/M 80
;name ('TURBO')
; DASMed version of TURBO.COM, v3.0
; By W. Cirsovius
;; +++l6f66 l446c l7124 l2da4 l3135 l2df8
; l731f -> $STR$ in Teil 6
;;; RTL l0af5
;;; MENUE -----
;;; EDITOR l42a1 l3918 l2fc1 l324b l32f5 (SEARCH)
;;; COMPILER l5039
;.z80
;aseg
;org 0100h
org PROGSTART
begin
FALSE equ 0
_TRUE equ 1
TERM equ _TRUE;FALSE
OS equ 0000h
DU equ 0004h ;TODO change to GETPATH and subdirs
BDOS equ 0005h
;TPAtop equ BDOS+1
NEDOOSMEMTOP=0xff00;0xdc06 ;TODO 0x0000?
Number equ 005dh
;TPA equ 0100h
;CP/M function codes:
;_resdsk equ 13 ;TODO
;_seldsk equ 14 ;
_open equ 15 ;
_close equ 16 ;
_srcfrs equ 17 ;
_srcnxt equ 18 ;
_delete equ 19 ;
_rdseq equ 20 ;
_wrseq equ 21 ;
_make equ 22 ;
_rename equ 23 ;TODO
_retdsk equ 25 ;removed TODO (return A=current drive)
_setdma equ 26 ;
_getalv equ 27 ;removed TODO
_getdpb equ 31 ;removed TODO
_rndrd equ 33 ;
_rndwr equ 34 ;
_filsiz equ 35 ;TODO (lib?)
RecLng equ 128 ; Standard record length
Dirlng equ 15
MaxParams equ 31
a_const equ 2
a_conin equ 3
a_conout equ 4
a_list equ 5
a_auxout equ 6
a_auxin equ 7
_.const equ (a_const-1)*3
_.conin equ (a_conin-1)*3
_.conout equ (a_conout-1)*3
_.list equ (a_list-1)*3
_.auxout equ (a_auxout-1)*3
_.auxin equ (a_auxin-1)*3
Fdrv equ 1
Fname equ 8
Fext equ 3
_SYS equ 10
_ex equ 12
DIRlen equ 16
_rrn equ 33 ;shift to random record number in FCB
FCBlen equ 36
FIB.rec equ 4 ; Pointer #records
FIB.reclen equ 6 ; Pointer record length
FIB.cur equ 8 ; Pointer to current record
FIB.FCB equ 12 ; Pointer to FCB
FIBlen equ FIB.FCB+FCBlen ; FIB length less buffer
FIB.buff equ FIBlen ; Pointer to buffer
FIBtype equ 00001111b
rd.bit equ 4
wr.bit equ 5
out.bit equ 6
in.bit equ 7
_.in equ 10000000b
_.out equ 01000000b
_.read equ 00010000b
FixRecLen equ 4 ; Fixed record length
Rec.Wr.bit equ 0
Rec.New.bit equ 1
Rec.Wr equ 01b
Rec.New equ 10b
RAMdevice equ 6
HeapLen equ 4 ; Heap administration
HeapLOadr equ 0 ; Address location
HeapHIadr equ 1
HeapLOlen equ 2 ; Length location
HeapHIlen equ 3
null equ 00h
bs equ 08h
tab equ 09h
lf equ 0ah
cr equ 0dh
eof equ 1ah
esc equ 1bh
CtrlC equ 'C'-'@'
Xoff equ 'S'-'@'
a_CAN equ 'U'-'@'
CtrlX equ 'X'-'@'
;DEL equ 7fh
LoMask equ 00001111b
DPBMASK equ 00011111b
NOMSB equ 01111111b
MSB equ 10000000b
LSB equ 00000001b
MMSB equ 1000000000000000b
MINWID equ 56 ; Min width for filename
MAXINT equ 32767
DefSTR equ 8
_LB equ 0
_MB equ 7
sgn.bit equ 7
sign.bit equ 10000000b
mant.len equ 5 ; Byte length of mantissa
Real.Len equ 6 ; Length of real
bit.len equ 8 ; Bits in a byte
exp.offset equ 080h ; Offset in exponent
Exp.One equ exp.offset+1 ; Exponent for >=1.0
int.max equ exp.offset+15 ; Max exponent for an integer
mant.bits equ mant.len*bit.len
real.dig equ 24 ; Length of mantissa
real.field equ 7 ; Real field size
real.ASCII equ 12 ; Decimal places
ExpFix equ 77 ; Exponent fix for real to ASCII
ExpRange equ 0d9h ; Exponent range
sqr.exp equ 014h ; SQRT exponent fix
sin.min equ 06ch ; SIN/COS minimum exponent
ln.min equ 067h ; LN minimum exponent
exp.max equ 088h ; EXP maximum exponent
dot.bit equ 6 ; Status of dot in real
exps.bit equ 5 ; Sign of exponent
exp.bit equ 4 ; Exponent
l00fe equ 254 ; Mystery editor size
MEMGAP equ 708 ; Memory gap at top of memory
StkSpc equ 1024 ; Stack space
_SavLen equ 8192
_RST equ 7 ; ** CAUTION **
RSTADDR equ _RST*8 ;SHL 3 ; RST address (0x0038H)
RST equ 11000111b + RSTADDR; RST instruction (0xFFH)
a_OVLADR equ 9000h ; Overlay load address
_LD.A equ 03eh ; LD A,xx
_LD.BC equ 001h ; LD BC,xxxx
_LD.DE equ 011h ; LD DE,xxxx
_LD.HL equ 021h ; LD HL,xxxx
_LD.SP equ 031h ; LD SP,xxxx
_LD_a_DE equ 5bedh ; LD DE,(xxxx)
_LD_a_HL equ 02ah ; LD HL,(xxxx)
_LDHL_a equ 022h ; LD (xxxx),HL
_LDA_a equ 032h ; LD (xxxx),A
_JP equ 0c3h ; JP xxxx
_CALL equ 0cdh ; CALL addr
_JPZ equ 0cah ; JP Z,xxxx
_EXX equ 0d9h ; EXX
_POP.HL equ 0e1h ; POP HL
_PUSH.HL equ 0e5h ; PUSH HL
_INC.HL equ 023h ; PUSH HL
_DEC.HL equ 02bh ; PUSH HL
;
skip equ 03eh ; LD A,xx
skip.2 equ 001h ; LD BC,xx
skip.3 equ 011h ; LD DE,xx
_LinLen equ 127
_MaxBuf equ 126 ; Max line input
_MaxSamp equ 30 ; Max sample input
_Ahead equ 20 ; Size of ahead buffer
set.len equ 32
DefWITH equ 2
_Byte equ 1
_Addr equ 2
_Array equ 1
_Record equ 2
_Set equ 3
_Ptr equ 4
_RecF equ 5
_TxtF equ 6
_UntF equ 7
_String equ 8
_Real equ 9
_Integ equ 10
_Bool equ 11
_Char equ 12
;13=element of a set?
_Label equ 1
_Const equ 2
_Type equ 3
_Var equ 4
_Proc equ 5
_Overly equ 7
_Begin equ 8
;
; Option selection bits
;
__Ropt equ 00000010b
__Uopt equ 00001000b
;
_Iopt equ 0
_Ropt equ 1
_Aopt equ 2
_Uopt equ 3
_Xopt equ 4
_Vopt equ 5
_Bopt equ 6
_Copt equ 7
;
; Search option list
;
_W equ 0
_N equ 1
_U equ 2
_G equ 3
_B equ 4
;
; Error levels
;
_BRK equ 0 ; User break
_IO equ 1 ; I/O error
_RT equ 2 ; Run time error
;
; BREAK error
;
_CBRK equ 1
;
; Compiler errors
;
_ColExp equ 1
_SemiExp equ 2
_CommaExp equ 3
_LftPar equ 4
_RgtPar equ 5
_EquExp equ 6
_AssigExp equ 7
_LftBrExp equ 8
_RgtBrExp equ 9
_DotExp equ 10
_TwoDots equ 11
_BEGINexp equ 12
_NoDO equ 13
_End equ 14
_NoOF equ 15
_SUBexp equ 16
_StrIdx equ 17
_NoDOWN_TO equ 18
_BoolExp equ 20
_FileVarExp equ 21
_IntConst equ 22
_IntExpr equ 23
_IntVarExp equ 24
_IntRealCexp equ 25
_NumExprExp equ 26
_NumVarExp equ 27
_PtrVarExp equ 28
_RecVarExp equ 29
_SimTyp equ 30
_SimpExpr equ 31
_StrgConExp equ 32
_StrgExpExp equ 33
_StrgVarExp equ 34
_MustTextFile equ 35
_TypeExp equ 36
_UntFileExp equ 37
_UnkLabel equ 40
_Undef equ 41
_InkPointer equ 42
_DoubleLab equ 43
_InvType equ 44
_ConstRange equ 45
_IllCASE equ 46
_IllOps equ 47
_InvResult equ 48
_IllStrgLen equ 49
_StrConst equ 50
_IllSkalar equ 51
_IllLimit equ 52
_ResWord equ 53
_IllAss equ 54
_StrConLong equ 55
_IntegErr equ 56
_RealErr equ 57
_IllChar equ 58
_IllConst equ 60
_InvFilPtr equ 61
_NoStruktVar equ 62
_IllTxtFile equ 63
_IllFileType equ 64
_NoUntypeFile equ 65
_InvIO equ 66
_VarFile equ 67
_FileF equ 68
_InvSetOrder equ 69
_IllSetRange equ 70
_IllGOTO equ 71
_IllLabel equ 72
_UndefFORW equ 73
_IllINLINE equ 74
_InvalABS equ 75
_OvlFORW equ 76
_OvlDirErr equ 77
_NoFileErr equ 90
_IllSrcEnd equ 91
_NoOvl equ 92
_CompDirec equ 93
_INCLerr equ 96
_TooManyWITH equ 97
_MemOvfl equ 98
_CompOvfl equ 99
_IndxErr equ 144
_RngErr equ 145
_ABORT equ 202
_FndRTerr equ 200
_DskFull equ 250
;
; Run-Time errors
;
_FLPovfl equ 1 ; 0x01
_DivZero equ 2 ; 0x02
_NegSqrt equ 3 ; 0x03
_LNerr equ 4 ; 0x04
_StrLenErr equ 16 ; 0x10
_TruncOvl equ 146 ; 0x92
_OVLerr equ 240 ; 0xf0
_HeapErr equ 255 ; 0xff
;
; Run-Time I/O errors
;
_NoFile equ 1 ; 0x01
_NoRead equ 2 ; 0x02
_NoWrite equ 3 ; 0x03
_BlkErr equ 4 ; 0x04
_IllNum equ 16 ; 0x10
_IllIO equ 32 ; 0x20
_DirErr equ 33 ; 0x21
_StdAssErr equ 34 ; 0x22
_InvRec equ 144 ; 0x90
_SeekEOF equ 145 ; 0x91
_IllEOF equ 153 ; 0x99
_WrErr equ 240 ; 0xF0
_DirFull equ 241 ; 0xF1
_OvflErr equ 242 ; 0xF2
_NoClose equ 255 ; 0xFF
TPhead equ 21 ; Header code length for ERROR
_Video equ 7 ; Status
a_DUMMY equ 04d2h
;l0300 equ 0300h
;l0800 equ 0800h
l07d0 equ 07d0h
l00a0 equ 00a0h ; Keypressed
l00a3 equ 00a3h ; Read KBD
l00a6 equ 00a6h ; Console output
l00a9 equ 00a9h ; List output
l00ac equ 00ach ; Auxiliary output
l00af equ 00afh ; Auxiliary input
l00b2 equ 00b2h ; Console output
l00b5 equ 00b5h ; Read USR
l00b8 equ 00b8h ; Base FIB
l00ba equ 00bah ; ConinFIB
l00bc equ 00bch ; LstFIB
l00be equ 00beh ; AuxFIB
l00c0 equ 00c0h ; UsrFIB
l00c2 equ 00c2h ; StdIOdev
l00c4 equ 00c4h ; Heap pointer
l00c6 equ 00c6h ; Recursion pointer
l00c8 equ 00c8h ; Four byte random value
l00cc equ 00cch ; Base PC
l00ce equ 00ceh ; Current PC
l00d0 equ 00d0h ; I/O result
l00d1 equ 00d1h ; Buffer length
l00d2 equ 00d2h ; RTL top of memory
l00d4 equ 00d4h ; Current pointer
l00d6 equ 00d6h ; Top pointer
l00d8 equ 00d8h ; Run mode
l00d9 equ 00d9h ; + JP xxxx
l00da equ 00dah ; + Restart vector
l00dc equ 00dch ; Overlay drive
l00dd equ 00ddh ; $C mode
l00e0 equ 00e0h ; Video mode
l00e8 equ 00e8h ; Pointer ????
l00f4 equ 00f4h ; Available memory
l0000 equ 00h
l0001 equ 01h
l0002 equ 02h
l0005 equ 05h
l0008 equ 08h
l000c equ 0ch
l000d equ 0dh ;for save environment
l0015 equ 15h
;l0019 equ 19h
l0024 equ 24h
l0030 equ 30h
l005c equ 5ch
l0080 equ 80h
l0081 equ 81h
l00b0 equ 00b0h
l00de equ 0deh
l00e2 equ 0e2h
l00e4 equ 0e4h
l00e6 equ 0e6h
l00e9 equ 0e9h
l00ea equ 0eah
l00ec equ 0ech
l00ed equ 0edh
l00f0 equ 0f0h
l00f2 equ 0f2h
l00f6 equ 0f6h
l00f8 equ 0f8h
lfff3 equ 0fff3h
lfffc equ 0fffch
lffff equ 0ffffh
l0100:
if TERM
call initstdio
else
OS_HIDEFROMPARENT
ld e,6 ;textmode
OS_SETGFX
endif
progstartaddr=$+1
jp l20e2 ; Jump over Run Time Library
;
; %%%%%%%%%%%%%%%%%%%%%%%%%
; %%% RUN TIME ROUTINES %%%
; %%%%%%%%%%%%%%%%%%%%%%%%%
;
db 0cdh,0abh
db 'Copyright (C) 1985 BORLAND Inc',null
l0124:
db 4 ; CPU speed
db 0,0a1h,'B'
;
; &&&&&&&&&&&&&&&&&&
; &&& PATCH AREA &&&
; &&&&&&&&&&&&&&&&&&
;
l0128:
cp 0fch ; Test special key
jp z,l2e8f
cp esc ; Test ESCape
jp z,l2e8f
jp l2e88
;
ds 30
;
l0153:
db TermLen
db 'NedoOS BDOS';'Schneider Joyce'
TermLen equ $-l0153-1
db '12864'
l0168:
db 80;90 ; Screen columns
l0169:
dw 25;31 ; Screen lines
;
; Lead in sequence: Leave 24x80 mode
;
l016b:
db 0;db 2,esc,'y'
;
db 1bh,'Y ',1,1,1dh
db 3,3,1bh,1bh,1bh,0d5h
;
; Lead out sequence: Enter 24x80 mode
;
l017b:
db 0;db 2,esc,'x'
;
db 0,0,1ch,0,17h,17h
db 1dh,17h,17h,0efh,9eh,0cdh,0bdh
;
;setxy sequence
;not used in NedoOS
l018b:
db 4,esc,'Y',0,0
ds 11
ll018b equ $-l018b
l019b:
db 1 ; Binary indicator (1 is binary)
l019c:
db ' ' ; Offset for column
l019d:
db ' ' ; Offset for row
l019e:
db 4 ; Position of column
l019f:
db 3 ; Position of row
l01a0:
dw 0
;
; Clear display
;not used in NedoOS
l01a2:
db 2,esc,'E'
ds 3
;
; Home cursor
;not used in NedoOS
l01a8:
db 2,esc,'H'
ds 3
;
; Insert line
;if zero in first byte, function not implemented in this terminal
l01ae:
db 0;db 2,esc,'L'
ds 3
;
; Delete line
;if zero in first byte, function not implemented in this terminal
l01b4:
db 0;db 2,esc,'M'
ds 3
l01ba:
dw 0
;
; Clear to end of line
;if zero in first byte, function not implemented in this terminal
l01bc:
if TERM
db 1
else
db 0;db 2,esc,'K'
endif
ds 3
;
; Turn off inverse
;
l01c2:
db 2,esc,'q'
ds 3
;
; Turn on inverse
;
l01c8:
db 2,esc,'p'
ds 3
l01ce:
dw 0
;
; Print control string ^HL on console
; C set if control not defined
;
l01d0:
ld a,(hl) ; Get character
or a ; Test defined
scf
ret z ; Nope as C set says
l01d4:
inc hl
push af
push hl
push ix ;TODO remove?
push iy
ld a,(hl) ; Get character
if TERM
PRCHAR_ ;call l01e8 ; Put to console
else
PRCHAR ;call l01e8 ; Put to console
endif
pop iy
pop ix ;TODO remove?
pop hl
pop af
dec a
ret z
jr l01d4
;
; Give new line on console
;
l01e1:
call l0200
db cr,lf,null
ret
;
; Put character on console
;
l01e8:
push ix ;TODO remove?
push iy
;ld l,a
;push hl ; Push onto stack
if TERM
PRCHAR_ ;call l00a6 ; Put to console
else
PRCHAR ;call l00a6 ; Put to console
endif
pop iy
pop ix ;TODO remove?
ret
;
; Check character for attribute
; MSB set for normal output
;
l01ee:
cp MSB ; Test attribute set
call c,setlowvideo ; Nope, set invers video
call nc,setnormvideo ; Yeap, set normal video
and NOMSB ; Strip off attribute
jr l01e8
;
; Print immediate control string on console
;
l01fa:
push hl
ld hl,l01ee ; Get new output routine
jr l0204
;
; Print immediate string on console
;
l0200:
push hl
ld hl,l01e8 ; Get new output routine
l0204:
ld (l0213),hl ; Change output vector
pop hl
ex (sp),hl ; Get pointer to string
push af
push bc
push de
l020c:
ld a,(hl) ; Get character
inc hl
or a ; Test end
jr z,l0218 ; Yeap
push hl
l0213 equ $+1
call a_DUMMY ; Process output
pop hl
jr l020c
l0218:
pop de
pop bc
pop af
ex (sp),hl
ret
;
; Delay by value in reg HL
;
l021d:
ld a,l
or h ; Test any value given
ret z ; Nope
ld a,(l0124) ; Get CPU speed
add a,a
add a,a
add a,a ; Build delay value
l0226:
ex (sp),hl ; 5 cycles
ex (sp),hl ; 10 cycles
ex (sp),hl ; 15 cycles
ex (sp),hl ; 20 cycles
push bc ; 23 cycles
ld bc,1234 ; 26 cycles
pop bc ; 29 cycles
dec a ; 30 cycles
jr nz,l0226
dec hl
jr l021d
;
; Give control and delay if control defined
;
l0235:
call l01d0 ; Give control
ret c ; Not defined
ld hl,(l01ce) ; Get value
jr l021d ; Delay
;
; Clear screen
;
l023e:
push af
push bc
push de
push hl
if 1==1
push ix ;TODO remove?
push iy ;needed!!!
if TERM
ld de,0
SETXY_
CLS_ ;print 25 lines of spaces except one
else
ld e,0
OS_CLS
endif
pop iy
pop ix ;TODO remove?
else
ld hl,l01a8
call l0235 ; Home cursor
ld hl,l01a2
l024b:
call l01d0 ; Clear display
endif
ld hl,(l01ba)
call nc,l021d ; Delay if defined
pop hl
pop de
pop bc
pop af
ret
;
; Delete line
;
l0259:
if 1==1
;jr $ ;TODO
else
push af
push bc
push de
push hl
ld hl,l01b4
jr l024b ; Delete line
endif
;
; Insert line
;
l0262:
if 1==1
;jr $ ;TODO
else
push af
push bc
push de
push hl
ld hl,l01ae
jr l024b ; Insert line
endif
;
; Set low video
;
setlowvideo:
push af
ld a,(l00e0) ;ok ;FIXME ; Get video mode
or a ; Test low mode already set
jr z,l0282 ; Yeap, skip
if 1==1
push bc
push de
push hl
push ix
push iy
xor a
ld (l00e0),a ;ok ;FIXME ; Set video mode
if TERM
ld de,0x0007
else
ld e,0x07;0x38
endif
l027c:
if TERM
SETCOLOR_
else
OS_SETCOLOR
endif
pop iy
pop ix
pop hl
pop de
pop bc
else
push bc
push de
push hl
xor a
ld (l00e0),a ;ok ;FIXME ; Set video mode
ld hl,l01c8 ; Set attribute
l027c:
call l0235 ; Give control
pop hl
pop de
pop bc
endif
l0282:
pop af
ret
;
; Set normal video
;
setnormvideo:
push af
ld a,(l00e0) ;ok ;FIXME ; Get video mode
cp -1 ; Test normal mode already set
jr z,l0282 ; Yeap, skip
if 1==1
push bc
push de
push hl
push ix
push iy
ld a,-1
ld (l00e0),a ;ok ;FIXME ; Set video mode
if TERM
ld de,0x000f
else
ld e,0x47;0x07
endif
jr l027c
else
push bc
push de
push hl
ld a,-1
ld (l00e0),a ;ok ;FIXME ; Set video mode
ld hl,l01c2 ; Reset attribute
jr l027c
endif
;
; Erase to end of line
;
l0299:
if 1==1
push af
push bc
push de
push hl
if TERM
push ix
push iy
call clearrestofline
pop iy
pop ix
endif
pop hl
pop de
pop bc
pop af
ret
else
push af
push bc
push de
push hl
ld hl,l01bc ; Clear to end of line
jr l027c
endif
;
; Position cursor with X (column) in reg H and y (row) in reg L
;
l02a2:
if 1==1
push af
push bc
push de
push hl
push ix
push iy
ld d,l
ld e,h
;dec d
;dec e
if TERM
SETXY_
else
OS_SETXY
endif
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ret
else
push af
push bc
push de
push hl
push hl
ld de,l00f0
ld hl,l018b
ld bc,ll018b
ldir ; Unpack control string
pop de ; Get back coordinates
ld a,(l019e) ; Get position of column
ld c,a
ld a,(l019c) ; Get offset for column
add a,d ; Build real value
push de
call l02dc ; Store it
pop de
ld a,(l019f) ; Get position of row
ld c,a
ld a,(l019d) ; Get offset for row
add a,e ; Build real value
call l02dc ; Store it
ld hl,l00f0
call l01d0 ; Give control
ld hl,(l01a0) ; Get delay value
call l021d ; Delay a bit
pop hl
pop de
pop bc
pop af
ret
endif
;
; Store Accu in position in reg C
;
l02dc:
ld hl,l00f0
ld b,0
add hl,bc ; Position in string
ex de,hl
ld hl,l019b
inc (hl) ; Test binary
dec (hl)
jr z,l02ec ; Nope, build ASCII
ld (de),a ; Store value
ret
l02ec:
dec de ; Fix for hi ASCII
dec de
ld hl,l0307+3 ; Point to divisor
ld b,3 ; Set length
l02f3:
dec hl
ld c,'0'-1 ; Init ASCII
l02f6:
inc c ; Fix quotient
sub (hl) ; Divide
jr nc,l02f6
add a,(hl) ; Build last value
push af
ld a,c
cp '0' ; Test zero
jr z,l0302 ; Skip if so
ld (de),a ; Store ASCII
l0302:
inc de
pop af
djnz l02f3
ret
;
l0307:
db 1,10,100
;
; Set lead in
;
l030a:
ld hl,l016b ; Give lead in
jp l0235
;
; Set lead out
;
l0310:
ld hl,l017b ; Give lead out
jp l0235
;
; Test key pressed
; EXIT Reg HL holds 1 if key pressed
;
l0316:
;ld de,_.const
;call l035f ; Get state
;and 1 ; Extract the bit
xor a ;TODO
jr l0326 ; Expand result to 16 bit
;
; Read character from console
; EXIT Reg HL holds character
;
l0320:
ld de,_.conin
l0323:
;call l035f ; Get input
push ix ;TODO remove?
push iy
if TERM
l0323_nokey
GETKEY_
or a
jr z,l0323_nokey
else
GET_KEY
endif
pop iy
pop ix ;TODO remove?
l0326:
ld l,a ; Expand result to 16 bit
ld h,0
ret
;
; Read character from auxiliary device
; EXIT Reg HL holds character
;
l032a:
jr l0320 ;??? from console
;ld de,_.auxin ; Set function
;jr l0323 ; Do thru BIOS
;
; Write character to list device
; ENTRY Character on stack
;
l032f:
jr l0339 ;??? to screen
;ld de,_.list ; Set function
;jr l033c ; Do thru BIOS
;
; Write character to auxiliary device
; ENTRY Character on stack
;
l0334:
jr l0339 ;??? to screen
;ld de,_.auxout ; Set function
;jr l033c ; Do thru BIOS
;
; Write character to console
; ENTRY Character on stack
;
l0339:
pop hl
pop bc ; Get character
push hl
ld a,c
push af
push bc
push de
push hl
push ix
push iy
if TERM
PRCHAR_
else
PRCHAR
endif
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ret
if TERM
include "../_sdk/stdio.asm"
endif
if 1==0
;ld de,_.conout ; Set function
l033c:
pop hl
pop bc ; Get character
push hl
ld a,(l00dd) ;ok ;FIXME ; Get $C mode
or a
jr z,l035f ; $C-, so skip testing
push de
push bc
call l00a0 ; Test key pressed
ld a,h
or l ; Nope
jr z,l035d
call readfromkbd ; Read character
cp Xoff ; Test XOFF
jr nz,l035d
call readfromkbd
cp CtrlC ; Test abort
jp z,l20d4 ; Halt if so
l035d:
pop bc
pop de
;
; Do BIOS internal call
;de=jp addr
l035f:
ret
;ld hl,(OS+1) ; Fetch base vector
;add hl,de ; Add osffset
;jp (hl) ; Go
endif
;
; Init TURBO program
; ENTRY Reg HL holds top of RAM
; Reg B holds break mode
; ($C- B=00)
; ($C+ B=FF)
; Reg C holds interrupt mode
; ($U- C=00)
; ($U+ C=rst)
; [rst may be the opcode for the requested
; RST opcode, typically F7 or EF]
;
l0364:
ld (l00d2),hl ;ok ;FIXME ; Save address
ld a,b
ld (l00dd),a ;ok ;FIXME ; Set $C mode
ld a,c ; Get $U
or a
jr z,l037a ; No interrupt
;ld a,_JP ; Set JP to interrupt
;ld (RSTADDR),a
;ld hl,l1ffb
;ld (RSTADDR+1),hl ; Change vector ;???
l037a:
ld hl,l03a5
ld de,l00a0
ld bc,ll0018
ldir ; Unpack I/O
ld hl,l03bd
ld de,l00b8
ld bc,ll000c
ldir ; Init FIB
xor a
ld l,a
ld h,a
ld (l00d0),a ;ok ;FIXME ; Clear I/O error
ld (l00d4),hl ;ok ;FIXME ; Clear some pointers
ld (l00d6),hl ;ok ;FIXME
ld a,_MaxBuf
ld (l00d1),a ;ok ;FIXME ; Set buffer length
ld (l00e0),a ;ok ;FIXME ; Set video mode
ret
;
; Character I/O table moved into 0x00A0
;
l03a5:
jp l0316 ; 0x00A0 : Keypressed
jp l0320 ; 0x00A3 : Read KBD
jp l0339 ; 0x00A6 : Console output
jp l032f ; 0x00A9 : List output
jp l0334 ; 0x00AC : Auxiliary output
jp l032a ; 0x00AF : Auxiliary input
jp l0339 ; 0x00B2 : Console output
jp l0320 ; 0x00B5 : Read KBD
ll0018 equ $-l03a5
;
; Standard IO control table
;
l03bd:
db 11000001b ; 0x00B8 : Input Output for CON
db 0
db 10000010b ; 0x00BA : Input for KBD
db 0
db 01000011b ; 0x00BC : Output for LST
db 0
db 11000100b ; 0x00BE : Input Output for AUX
db 0
db 11000101b ; 0x00C0 : Input Output for USR
db 0
db 11000001b ; 0x00C2 : Input Output for CON
db 0
ll000c equ $-l03bd
;
; Put character to console
;
puttoconsole_a:
push bc
push de
push hl
push ix
push iy
push af
if TERM
PRCHAR_
else
PRCHAR
endif
;ld l,a
;ld h,0
;push hl
;call l00a6 ; Put to console
pop af
l03d9:
pop iy
pop ix
pop hl
pop de
pop bc
ret
;
; Read character from keyboard
;
readfromkbd:
push bc
push de
push hl
push ix
push iy
if TERM
readfromkbd_nokey
call yieldgetkeyloop ;YIELDGETKEYLOOP
or a
jr z,readfromkbd_nokey
else
ld e,0x78
OS_PRATTR
YIELDGETKEYLOOP
push af
ld e,0x47
OS_PRATTR
pop af
endif
;call l00a3 ; Read KBD
;ld a,l
jr l03d9
;
; Parse file, allow wildcards
;
l03ee:
ld c,0xff-FALSE ; Set flag
jr l03fe
;
; Parse file, wildcards not allowed
;
l03f2:
ld c,FALSE
ld de,(l00d2) ; Get top of memory for input
l03f8:
inc de
ld a,(de)
cp ' ' ; Skip blanks
jr z,l03f8
l03fe:
ld hl,l005c+Fdrv+Fname
ld b,Fext
call l047b ; Blank extension
l0406:
ld a,(de) ; Get character
call doupcase ; Convert to upper case
cp 'A' ; Test posible drive
jr c,l0420
cp 'P'+1
jr nc,l0420
ld b,a ; Save drive
inc de
ld a,(de)
cp ':' ; Verify drive
jr nz,l041f
ld a,b
sub 'A'-1 ; Make binary
inc de
jr l0421
l041f:
dec de
l0420:
xor a ; Set default drive
l0421:
ld hl,l005c
ld (hl),a ; Save drive
inc hl
inc c ; Test wildcards allowed
dec c
jr z,l0443 ; Nope
ld a,(de) ; Get character
call l0482 ; Test delimiter
jr nz,l0443 ; Nope
cp '?' ; Test single wildcard
jr z,l0443 ; Yeap
cp '*' ; Test wildcard
jr z,l0443 ; Yeap
cp '.' ; Test dot
jr z,l0443 ; Yeap
ld b,Fname+Fext
call l0477 ; Set wildcard
jr l0453 ; Go init remainder
l0443:
ld b,Fname
call l045e ; Parse name
ld a,(de)
cp '.' ; Test extension delimiter
jr nz,l0453 ; Nope
inc de
ld b,Fext
call l045e ; Parse extension
l0453:
ld hl,l005c+_ex
ld b,FCBlen-_ex
l0458:
ld (hl),0 ; Clear remainder of FCB
inc hl
djnz l0458
ret
;
; Parse B characters
;
l045e:
ld a,(de) ; Get character
inc c ; Test wildcard allowed
dec c
jr z,l046b ; Nope
cp '?' ; Test single wildcard
jr z,l0470 ; Save it
cp '*' ; Test multiple wildcards
jr z,l0476 ; Map them
l046b:
call l0482 ; Test delimiter
jr z,l047b ; Yeap
l0470:
ld (hl),a ; Store character
inc hl
inc de
djnz l045e
ret
l0476:
inc de
;
; Set B wildcards
;
l0477:
ld a,'?' ; Set wildcard character
jr l047d
;
; Blank B positions in ^HL
;
l047b:
ld a,' '
l047d:
ld (hl),a ; Save character
inc hl
djnz l047d
ret
;
; Test delimiter
; Z set says yes
;
l0482:
call doupcase ; Convert to upper case
cp ' ' ; Test control
jr c,l0496 ; Yeap, it's a delimiter
push hl
push bc
ld hl,l0498
ld bc,ll0498
cpir ; Find in table
pop bc
pop hl
ret
l0496:
cp a
ret
;
l0498:
db ' .,;:=?*[]<>{}'
ll0498 equ $-l0498
;
; Convert character to UPPER case
;
doupcase:
cp 'a' ; Test range
ret c
cp 'z'+1
ret nc
sub 'a'-'A' ; Convert to upper case
ret
;
; Print hex word in reg HL
;
l04af:
ld a,h ; Get hi
call l04b4 ; Print it
ld a,l ; Followed by lo
;
; Print hex byte in Accu
;
l04b4:
push af
rra ; Isolate hi bits
rra
rra
rra
call l04bd ; Convert them
pop af
l04bd:
and LoMask ; Mak bits
add a,090h ; Dirty trick
daa
adc a,040h
daa
jp puttoconsole_a ; Put to console
;
; Get byte from 16 bit
; ENTRY Reg HL holds 16 bit signed integer
; EXIT Accu holds 0 and carry set if HL<0
; Accu holds -1 and carry reset if HL>256
; Accu holds low part and carry reset else
;
l04c8:
xor a
scf
bit 7,h ; Test sign bit
ret nz ; Return 0 and C set if HL<0
ld a,h
or a
ld a,l
ret z ; Return LO if HI=0
ld a,-1 ; Else return -1
ret
;
; Test enough space
; ENTRY Reg HL holds 1st free address
; Reg DE holds last free address
; Reg BC holds top of ram
; Accu holds run mode
;
l04d4:
ld (l00d8),a ; Re/Set runmode (0 is TP menue)
push bc
call l1eaf ; Init heap
pop bc
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop)
or a
sbc hl,bc ; Test memory available
jp c,l20a8 ; Nope, exit
ex de,hl
pop de ; Get caller
ld sp,hl ; Set new stack
ld bc,-StkSpc
add hl,bc ; Allow some stack space
ld (l00c6),hl ; Set recursion pointer
xor a
ld l,a
ld h,a
ld (l00ce),hl ; Reset current PC
ld (l00dc),a ; Reset overlay drive
ld a,_JP
ld (l00d9),a ; Init restart
ld hl,l20de
ld (l00da),hl ; Set error vector
ex de,hl
ld (l00cc),hl ; Set base PC
jp (hl) ; Jump back to caller
;
; Start of recursive procedure or function
; ENTRY Reg BC holds bytes to be preserved
; Reg HL holds address of save area
;
l0508:
push hl
ld hl,(l00c6) ; Get recursion pointer
or a
sbc hl,bc ; Calculate new pointer
ld (l00c6),hl
ld de,(l00c4) ; Get heap pointer
or a
sbc hl,de ; Test against it
add hl,de
ex de,hl
pop hl
jp c,l1d75 ; Error if overlapping
ldir
ret
;
; End of recursive procedure or function
; ENTRY Reg BC holds bytes to be preserved
; Reg DE holds address of save area
;
l0522:
ld hl,(l00c6) ; Get recursion pointer
ldir ; Reload code
ld (l00c6),hl ; Update pointer
exx
ret
;
; Load real into registers
; ENTRY Reg HL points to real variable
; EXIT Regs HL,DE,BC hold number
;
l052c:
ld e,(hl) ; Get exponent
inc hl
ld d,(hl) ; Get LSB
inc hl
push de
ld e,(hl) ; Get 4th mantissa byte
inc hl
ld d,(hl) ; Get 3rd mantissa byte
inc hl
ld c,(hl) ; Get 2nd mantissa byte
inc hl
ld b,(hl) ; Get MSB
pop hl
ret
;
; move string to stack
; ENTRY Reg HL points to string
;
l053a:
pop ix ; Get caller
ex de,hl
ld a,(de) ; Get length of string
ld c,a
ld b,0
cpl ; Negate
ld l,a
ld h,-1
add hl,sp ; Fix stack
ld sp,hl
ex de,hl
inc bc
ldir ; move to stack
jp (ix) ; Exit
;
; move immediate string to stack
; ENTRY String started with length after caller
;
l054d:
pop de ; Get string pointer
ld a,(de) ; Get length
ld c,a
ld b,0 ; Expand for 16 bit
cpl ; Negate
ld l,a
ld h,-1
add hl,sp ; Fix stack
ld sp,hl
ex de,hl
inc bc
ldir ; move to stack
jp (hl)
;
; Push set onto stack
; ENTRY Reg HL points to set variable
; Reg C holds set length in bits
; Reg B holds set to be cleared
;
l055d:
pop ix ; Get caller
ex de,hl
ld hl,-set.len
add hl,sp ; Adjust stack for max set length
ld sp,hl
ex de,hl
push bc
inc b ; Test bits to clear
dec b
jr z,l0570 ; Nope
xor a
l056c:
ld (de),a ; Clear a part
inc de
djnz l056c
l0570:
ldir ; Save set on stack
pop bc
ld a,set.len
sub b
sub c ; Test remaining bits to clear
jr z,l057f ; Nope
ld b,a
xor a
l057b:
ld (de),a ; Clear bits
inc de
djnz l057b
l057f:
jp (ix)
;
; Initialize a set on stack
;
l0581:
pop ix ; Get caller
ld hl,-set.len
add hl,sp ; Fix stack
ld sp,hl
ld b,set.len ; Set count
xor a
l058b:
ld (hl),a ; Init set
inc hl
djnz l058b
jp (ix)
;
; Init one set element
; ENTRY Reg HL holds set value to be set
;
l0591:
pop ix
ld b,l ; Get value
call l05ba ; Get bit
l0597:
or (hl) ; Insert it
ld (hl),a
l0599:
jp (ix)
;
; Init a contiguous set value
; ENTRY Reg HL holds upper limit
; On stack pushed lower limit
;
l059b:
pop ix
pop de ; Get lower limit
ld a,l
sub e
jr c,l0599 ; Out of range
inc a
ld c,a
ld b,e ; Get low value
call l05ba ; Get bit
ld e,a
ld b,c ; Copy loop value
xor a
l05ab:
or e
sla e ; Shift bit
jr nc,l05b6
or (hl) ; Insert
ld (hl),a
inc hl ; Point to next
xor a
ld e,1 ; Init low bit for next
l05b6:
djnz l05ab
jr l0597 ; Set final one
;
; Access one set bit
; ENTRY Reg B holds numeric value of set element
; EXIT Accu holds bit
; Reg HL points to set loacation
;
l05ba:
ld a,b ; Get value
and 11111000b ; Mask it
rrca ; Divide by eight
rrca
rrca
add a,2 ; Fix position for stack
ld l,a
ld h,0
add hl,sp ; Get position
ld a,b
and 00000111b ; Mask bits
inc a
ld b,a
xor a
scf ; Init 1
l05cd:
rla ; Shift bit into correct position
djnz l05cd
ret
;
; Save real number
; ENTRY Reg HL points to real variable
; Alternative regs HL,DE,BC hold number
;
l05d1:
push hl ; Save pointer
exx
ex de,hl
ex (sp),hl ; Get back pointer
ld (hl),e ; Save exponent
inc hl
ld (hl),d ; Save LSB
inc hl
pop de
ld (hl),e ; Save 4th mantissa byte
inc hl
ld (hl),d ; Save 3rd byte
inc hl
ld (hl),c ; Save 2nd byte
inc hl
ld (hl),b ; Save MSB
ret
;
; Assign string from stack
; ENTRY Reg HL points to string to be assigned
; Reg B holds max length of this string
;
l05e2:
pop ix ; Get caller
ld a,b ; Get max
ex de,hl ; Swap pointer
ld hl,0
ld b,h
add hl,sp ; Fix stack for start of string
ld c,(hl) ; Get this length
push hl
add hl,bc ; Calculate new stack
l05ee:
inc hl
ex (sp),hl
cp c ; Test length
jr c,l05f4
ld a,c ; Get smaller one
l05f4:
ld (de),a ; Unpack length
inc de
inc hl
or a ; Test any character
jr z,l05fd ; Nope
ld c,a
ldir ; Unpack if so
l05fd:
pop hl
ld sp,hl
jp (ix)
;
; Assign string from stack
; ENTRY Reg B holds max length of string
;
l0601:
pop ix ; Get caller
ld a,b ; Get max
ld hl,0
ld b,h
add hl,sp ; Fix stack for start of string
ld c,(hl) ; Get this length
push hl
add hl,bc ; Calculate new stack
inc hl
ld e,(hl) ; Fetch address of string
inc hl
ld d,(hl)
jr l05ee ; Unpack it
;
; Assign set variable
; ENTRY Reg HL points to variable
; Reg BC holds length of set
;
l0612:
pop ix ; Get caller
ex de,hl
ld l,b ; Copy length
ld h,0
ld b,h
add hl,sp ; Point to start location
ldir ; Unpack set variable
ld hl,set.len
l061f:
add hl,sp ; Fix stack
ld sp,hl
jp (ix) ; Exit
;
; Assign set variable
; ENTRY Reg BC holds length of set
;
l0623:
pop ix ; Get caller
ld hl,set.len
add hl,sp ; Point to destination
ld e,(hl) ; Get it
inc hl
ld d,(hl)
ld l,b ; Copy length
ld h,0
ld b,h
add hl,sp ; Point to start location
ldir
ld hl,set.len+2 ; Remember address
jr l061f ; Fix stack
;
; Set set to stack
; ENTRY Reg HL holds address of set
; Reg B holds length of set
;
l0638:
pop ix ; Get caller
ex de,hl ; Swap source
ld a,b
cpl
ld l,a
ld h,-1 ; Get -length
add hl,sp ; Fix stack
ld sp,hl ; Set new
ld (hl),b ; Set length
inc hl
ld c,b ; Expand length
ld b,0
ex de,hl ; Get back source
ldir ; move to stack
jp (ix)
;
; Index check on compiler directive {$R+}
; ENTRY Reg HL holds current index
; Reg DE holds max index
;
l064c:
or a
sbc hl,de ; Verify limit ok
add hl,de
ret c ; Yeap
ld a,_IndxErr
jp l2027 ; Else process error
;
; Range check on compiler directive {$R+}
; ENTRY Reg HL holds actual value
; Reg DE holds low limit
; Reg BC holds range of value
;
l0656:
or a
sbc hl,de
or a
sbc hl,bc ; Test max
jr nc,l0661 ; Error
add hl,bc ; Restore value
add hl,de
ret
l0661:
ld a,_RngErr
jp l2027 ; Set error
;
; Set up FOR .. TO loop
; ENTRY Reg DE holds start value
; Reg HL holds end value
; EXIT Reg DE holds loops
; Reg HL holds start value
;
l0666:
or a
sbc hl,de ; Get difference
ex de,hl ; Into reg DE
l066a:
inc de ; Fix loop count
jp pe,l0671 ; Check any loop
ret p
jr l0672
l0671:
ret m
l0672:
ld de,0 ; Set no loop
ret
;
; Set up FOR .. DOWNTO loop
; ENTRY Reg DE holds start value
; Reg HL holds end value
; EXIT Reg DE holds loops
; Reg HL holds start value
;
l0676:
push de
ex de,hl
or a
sbc hl,de ; Get difference
ex de,hl
pop hl
jr l066a ; Build loop
;
; ################## The comparison package ###################
; # TRUE set (=1 on TURBO) if relation matches #
; # #
; # On all relational functions the assignment is as follows: #
; # #
; # INTEGER : DE:HL #
; # REAL : (Regs):(Regs)' #
; # STRING : (Stack):(next_stack) #
; # #
; #############################################################
;
; ********************************
; ********** Relation = **********
; ********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l067f:
or a
sbc hl,de ; Get difference
l0682:
ld hl,_TRUE ; Init TRUE
ret z ; Ok, same
dec hl ; Fix for FALSE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l0688:
call l0bdf ; Compare
jr l0682 ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l068d:
call l09b0 ; Compare
jr l0682 ; Set result
;
; *********************************
; ********** Relation <> **********
; *********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l0692:
or a
sbc hl,de ; Get difference
l0695:
ld hl,_TRUE ; Init TRUE
ret nz ; Ok, not same
dec hl ; Fix for FALSE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l069b:
call l0bdf ; Compare
jr l0695 ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l06a0:
call l09b0 ; Compare
jr l0695 ; Set result
;
; *********************************
; ********** Relation >= **********
; *********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l06a5:
call l0772 ; Check operands
l06a8:
ld hl,_TRUE ; Init TRUE
ret nc ; Ok if .GTE.
dec hl ; Else fix for FALSE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l06ae:
call l0bdf ; Compare
jr l06a8 ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l06b3:
call l09b0 ; Compare
jr l06a8 ; Set result
;
; *********************************
; ********** Relation <= **********
; *********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l06b8:
call l0772 ; Check operands
l06bb:
ld hl,_TRUE ; Init TRUE
ret z ; Ok if .EQ.
ret c ; Ok if .LT.
dec hl ; Else fix for FALSE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l06c2:
call l0bdf ; Compare
jr l06bb ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l06c7:
call l09b0 ; Compare
jr l06bb ; Set result
;
; ********************************
; ********** Relation > **********
; ********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l06cc:
call l0772 ; Check operands
l06cf:
ld hl,FALSE ; Init FALSE
ret z ; Ok if .EQ.
ret c ; Ok if .LT.
inc hl ; Else fix for TRUE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l06d6:
call l0bdf ; Compare
jr l06cf ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l06db:
call l09b0 ; Compare
jr l06cf ; Set result
;
; ********************************
; ********** Relation < **********
; ********************************
;
; %%%%%%%%%%%%%
; %% INTEGER %%
; %%%%%%%%%%%%%
;
l06e0:
call l0772 ; Check operands
l06e3:
ld hl,_TRUE ; Init TRUE
ret c ; Ok if .LT.
dec hl ; Else fix for FALSE
ret
;
; %%%%%%%%%%
; %% REAL %%
; %%%%%%%%%%
;
l06e9:
call l0bdf ; Compare
jr l06e3 ; Set result
;
; %%%%%%%%%%%%
; %% STRING %%
; %%%%%%%%%%%%
;
l06ee:
call l09b0 ; Compare
jr l06e3 ; Set result
;
; ################# End of comparison package #################
;
; Function SQR(integer):integer;
; ENTRY Reg HL holds number
; EXIT Reg HL holds power
;
l06f3:
ld d,h ; Copy number
ld e,l
;
; Operator *
; Multiply signed integers
; ENTRY Reg DE holds multiplicand
; Reg HL holds multiplier
; EXIT Reg HL holds product
;
l06f5:
ld c,e ; Copy multiplicand
ld b,d
ex de,hl
ld hl,0 ; Init product
ld a,d
or a ; Test word
ld a,16
jr nz,l0704 ; Yeap, set bit count
ld d,e
ld a,8 ; Change bit count
l0704:
add hl,hl ; Do the multiplication
ex de,hl
add hl,hl
ex de,hl
jr nc,l070b
add hl,bc
l070b:
dec a
jr nz,l0704
ret
;
; Operator DIV
; Divide signed integers
; ENTRY Reg DE holds dividend
; Reg HL holds divisor
; EXIT Reg HL holds quotient
; Reg DE holds remainder
;
l070f:
ld a,h ; Test zero divisor
or l
jp z,l0a03 ; Divide by zero
ld a,h
xor d ; Calculate sign
push af
call l0780 ; Make both numbers positive
ex de,hl
call l0780
ex de,hl
ld b,h ; Copy divisor
ld c,l
xor a
ld h,a ; Clear result
ld l,a
ld a,17 ; Set bit count
l0726:
adc hl,hl ; Perform division
sbc hl,bc
jr nc,l072e
add hl,bc
scf
l072e:
ccf
rl e
rl d
dec a ; Test done
jr nz,l0726 ; Nope, loop on
ex de,hl
pop af ; Get resulting sign
ret p
jr l0783 ; Negate result
;
; Function RANDOM(integer):integer
; ENTRY Reg HL holds integer limit
; EXIT Reg HL holds random
;
l073b:
push hl
call l0792 ; Get random value
srl h ; Make positive, dividing by 2
rr l
pop de
ex de,hl
;
; Operator MOD
; Get modulo of signed integers
; ENTRY Reg DE holds dividend
; Reg HL holds divisor
; EXIT Reg HL holds remainder
;
l0745:
call l070f ; HL:=DE DIV HL;DE:=DE MOD HL
ex de,hl ; Swap remainder
bit 7,d ; Test result
ret z
jr l0783 ; Negate
;
; Operator SHL
; Shift left number
; ENTRY Reg DE holds number to be shifted
; Reg HL holds shift count
; EXIT Reg HL holds result
;
l074e:
call l0761 ; Get shift values
ret z ; End on zero
l0752:
add hl,hl ; Shift
djnz l0752
ret
;
; Operator SHR
; Shift right number
; ENTRY Reg DE holds number to be shifted
; Reg HL holds shift count
; EXIT Reg HL holds result
;
l0756:
call l0761 ; Get shift values
ret z ; End on zero
l075a:
srl h ; Shift
rr l
djnz l075a
ret
;
; Set shift values
; ENTRY Reg HL holds number to be shifted
; Reg DE holds shift count
; EXIT Reg B holds shift count
; Zero flag set on nothing to be shifted
; Reg HL may be preset to zero
;
l0761:
ex de,hl ; Swap factor
ld a,d ; Test hi zero value
or a
jr nz,l076e ; Nope, should be
ld a,e
cp 16 ; Test max length
jr nc,l076e ; Overflow
ld b,a
or a
ret
l076e:
xor a
ld h,a ; Clear result
ld l,a
ret
;
; Compare signed integers
; ENTRY Reg DE holds 1st number
; Reg HL holds 2nd number
; EXIT Zero flag set if DE=HL
; Carry flag set if DE<HL
;
l0772:
ex de,hl
ld a,h
xor d ; Test same signs
ld a,h
jp m,l077e ; Nope, fix carry
cp d ; Compare hi
ret nz
ld a,l
cp e ; Compare lo if hi is same
ret
l077e:
rla ; Get sign of first number
ret
;
; Function ABS(integer):integer;
; ENTRY Reg HL holds signed integer
; EXIT Reg HL holds positive integer
;
l0780:
bit _MB,h ; Test sign
ret z ; Already positive
l0783:
ld a,h ; Build one's complement
cpl
ld h,a
ld a,l
cpl
ld l,a
inc hl ; Fix for two's complement
ret
;
; Function ODD(integer):boolean
;
l078b:
ld a,l ; Get lo byte
and LSB ; Extract bit
ld l,a ; Expand to 16 bit
ld h,0
ret
;
; Get random value
; EXIT Regs BC and HL hold byte 3 and 4 of resulting random
; Reg DE holds middle part of real number
;
l0792:
ld bc,(l00c8+2) ;ok ;FIXME ; Load old values
ld de,(l00c8) ;ok ;FIXME
push bc ; Save them
push de
ld a,b ; Expand to 40 bits
ld b,c
ld c,d
ld d,e
ld e,0
rra ; Shift them all
rr b
rr c
rr d
rr e
pop hl
add hl,de ; Add to old
ex de,hl
pop hl
adc hl,bc
ld b,h
ld c,l
ld hl,0110001011101001b
add hl,de ; Fix them - add 62E9H
ld (l00c8),hl ;ok ;FIXME ; Save new values
ex de,hl
ld hl,0011011000011001b
adc hl,bc ; Add 3619H
ld (l00c8+2),hl ;ok ;FIXME
ld b,h ; Copy result
ld c,l
ret
;
; Convert positive integer to ASCII number
; ENTRY Reg IX points to ASCII buffer
; Reg HL holds integer
; EXIT Buffer filled
;
l07c6:
ld b,0 ; Init flag
ld de,10000
call l07e2 ; Start with 10000s
ld de,1000
call l07e2 ; Then 1000s
ld de,100
call l07e2 ; Then 100s
ld e,10
call l07e2 ; Then 10s
ld a,l ; Get remainder
jr l07ef
l07e2:
xor a ; Clear quotient
l07e3:
inc a ; Advance quotient
sbc hl,de ; Divide
jr nc,l07e3 ; Still positive
add hl,de ; Fix for last number
inc b ; Access flag
dec a ; Test zero digit
jr nz,l07ef ; Nope, so store result
dec b ; Test flag
ret z ; No leading zeroes
l07ef:
add a,'0' ; Make ASCII
ld (ix+0),a ; Save it
inc ix ; Advance buffer
ret
;
; Convert ASCII number to integer
; ENTRY Reg IX points to ASCII number
; EXIT Reg HL holds integer
; Carry set on overflow
;
cnv_int:
ld a,(ix+0)
sub '$' ; Test hex indicator
ld c,a ; Save flag
ld hl,0 ; Init result
jr nz,l0804
l0802:
inc ix ; Skip indicator
l0804:
ld a,(ix+0)
call doupcase ; Convert to upper case
sub '0' ; Strip off offset
jr c,l0837 ; Out of range
cp 9+1 ; Test decimal
jr c,l0820 ; Yeap
inc c ; Test hex allowed
dec c
jr nz,l0837 ; Nope
sub 'A'-'0'-10 ; Fix hex offset
cp 10 ; Verify correct range
jr c,l0837
cp 15+1
jr nc,l0837
l0820:
ld d,h ; Copy current number
ld e,l
add hl,hl ; * 2
ret c ; Overflow
add hl,hl ; * 4
ret c
inc c ; Test hex
dec c
jr nz,l082c
ld d,h ; Copy * 4
ld e,l
l082c:
add hl,de ; * 5 or * 8
ret c
add hl,hl ; * 10 or * 16
ret c
ld e,a
ld d,0
add hl,de ; Insert new digit
ret c
jr l0802
l0837:
ld a,c
or a ; Test hex
ret z ; Yeap
ld a,h
add a,a ; Get MSB into carry if decimal
ret
;
; Add two strings
; ENTRY Stack holds strings
; EXIT Stack holds combined string
;
l083d:
pop ix ; Get caller
pop hl
push hl
ld a,l ; Get length of 1st
ld h,0
inc hl
add hl,sp ; Point to 2nd
ld c,(hl)
add a,c ; Add lengthes
jr c,l0866 ; Too long
ld (hl),a ; Set new length
ex de,hl
ld hl,0
ld b,h
sbc hl,bc ; Prepare moving strings
add hl,sp
ld sp,hl
ex de,hl
push hl
inc bc
ldir ; move into right place
ex de,hl
pop hl
dec hl
dec de
ld c,a
inc bc
lddr
ex de,hl
inc hl
ld sp,hl
jp (ix)
l0866:
ld a,_StrLenErr ; Set error
jp l2029
;
; Function COPY(string,start,length):string
; ENTRY Start on stack, followed by string
; Reg HL holds length
; EXIT Substring on stack
;
l086b:
pop ix ; Get caller
call l04c8 ; Get length byte from integer
ld d,a
pop hl ; Get start
call l09dd ; Verify 1..255
ld e,a
pop hl ; Get length ( - and 1st character)
push hl
ld a,l
sub e ; Test against start
jr c,l0896 ; Out of bounds
inc d ; Test zero length
dec d
jr z,l0896 ; Yeap, done
cp d ; Compare against length
jr c,l0899 ; Nothing to move
ld c,d ; Fix a bit
ld b,0
ld h,b
add hl,sp
ld a,e
add a,d
ld d,h
ld e,l
dec a
ld l,a
ld h,b
add hl,sp
ld a,c
lddr ; Then move down
ex de,hl
jr l089f
l0896:
xor a ; Set zero length
jr l089c
l0899:
inc a ; Fix length
ld l,e
dec l ; Fix position
l089c:
ld h,0
add hl,sp ; Copy position
l089f:
ld (hl),a ; Store length
ld sp,hl ; Get stack
jp (ix) ; Exit
;
; Function LENGTH(string):integer
; ENTRY String on stack
; EXIT Reg HL holds length
;
l08a3:
pop ix ; Get caller
pop hl ; Get length ( - and 1st character)
push hl
ld a,l ; Save length
ld h,0
inc hl
add hl,sp
ld sp,hl ; Fix stack
ld l,a ; Get 16 bit length
ld h,0
jp (ix) ; Exit
;
; Function POS(substring,string):integer
; ENTRY String on stack, followed by substring
; EXIT Reg HL holds position, 0 is not found
;
l08b2:
pop ix ; Get caller
ld hl,0
ld d,h
add hl,sp ; Copy stack
ld e,(hl) ; Get length of main_string
ld c,e
inc hl
push hl
add hl,de ; Point to sub_string
ld e,(hl) ; Get length of sub_string
ld b,e
inc hl
push hl
add hl,de ; Point to end of both
push hl
pop iy ; Copy address
pop de ; Get sub_string
pop hl ; Get main_string
ld a,c
sub b ; Test range
jr c,l08dc ; Sub_string > main_string - no match
inc a ; Fix count
ld c,a
l08ce:
push bc
push de
push hl
l08d1:
ld a,(de)
cp (hl) ; Compare
jr z,l08e1 ; Maybe success
pop hl
pop de
pop bc
inc hl
dec c ; Test more to search
jr nz,l08ce ; Ok, then try next
l08dc:
ld hl,0 ; Set zero result
jr l08ef
l08e1:
inc hl
inc de
djnz l08d1 ; Loop thru sub_string
pop de
pop hl
pop bc
ld hl,0
add hl,sp ; Get pointers
ex de,hl
sbc hl,de ; Calculate resulting position
l08ef:
ld sp,iy ; Set stack
jp (ix) ; Exit
;
; Procedure DELETE(string,start,length)
; ENTRY Start on stack, followed by string
; Reg HL holds length
;
l08f3:
pop ix ; Get caller
call l04c8 ; Get length byte from integer
ld c,a
pop hl
call l09dd ; Verify length in range 1..255
ld e,a
pop hl ; Get start_string
ld a,(hl) ; Get length
sub e ; Test start > length
jr c,l091e ; Exit if so
inc c
dec c ; Test any length
jr z,l091e ; Nope, exit
sub c ; Test remaining count
jr c,l091c ; Nope, done
push af
ld a,(hl)
sub c
ld (hl),a
ld b,0
ld d,b
add hl,de ; Point to destination
ld d,h
ld e,l
add hl,bc ; Point to source
pop af
inc a
ld c,a
ldir ; Unpack
jr l091e
l091c:
dec e ; Adjust length
ld (hl),e ; Store it
l091e:
jp (ix) ; Exit
;
; Procedure INSERT(string,substring,start)
; ENTRY Pointer of substring on stack, followed by string
; Reg HL holds start
; Reg B holds max length of string
;
l0920:
pop ix ; Get caller
call l09dd ; Verify start in range 1..255
ld c,a
pop de ; Get sub_string
ld (l00e8),de ;ok ;FIXME
ld hl,0
add hl,sp ; Get string pointer
ld a,(de)
push af
add a,(hl) ; Get combined length
jr c,l0937 ; Truncate on overflow
cp b ; Compare against max
jr c,l0938 ; Ok
l0937:
ld a,b ; Set max defualt
l0938:
ld (de),a ; Save combined length
pop af ; Get length of substring
ld d,a
ld e,(hl)
sub c ; Get remainder
jr c,l096e ; Skip
inc a
ld l,a
ld a,d
add a,e
jr c,l0949
cp b
ld a,l
jr c,l0951
l0949:
ld a,b
sub e
jr c,l0973
sub c
jr c,l0973
inc a
l0951:
or a
jr z,l0973
push bc
push de
ld hl,(l00e8) ;ok ;FIXME ; Get back sub_string pointer
ld e,a
dec e
ld d,0
ld b,d
add hl,de
add hl,bc
pop de
push de
push hl
ld d,b
add hl,de
ex de,hl
pop hl
ld c,a
lddr ; move down
pop de
pop bc
jr l0973
l096e:
ld a,d
inc a
jr z,l098b
ld c,a
l0973:
ld a,b
sub c
inc a
cp e
jr c,l097a
ld a,e
l097a:
or a
jr z,l098b
ld hl,(l00e8) ;ok ;FIXME ; Get sub_string pointer
ld b,0
add hl,bc
ex de,hl
ld hl,1
add hl,sp
ld c,a
ldir ; move
l098b:
ld hl,0
ld d,h
add hl,sp ; Fix stack
ld e,(hl)
inc de
add hl,de
ld sp,hl ; Set stack
jp (ix) ; Exit
;
; Check assignment of string to character
; EXIT Reg L holds character
;
l0996:
pop ix ; Get caller
pop hl ; Get length and character
dec l ; Verify character only
jp nz,l0866 ; Error if not
ld l,h ; Unpack character
ld h,0
jp (ix) ; Exit
;
; Set character into string
;
l09a2:
ld hl,2
ld d,h
add hl,sp ; Point to string
ld e,(hl) ; Get length
inc de
add hl,de ; Point to top
ld a,(hl) ; Get character
ld (hl),1 ; Set length
inc hl
ld (hl),a ; Store character
ret
;
; Compare two strings
; ENTRY 1st stack 1st pushed, 2nd stack 2nd pushed
; EXIT Carry flag set if 1st<2nd
; Zero flag set if 1st=2nd
;
l09b0:
ld hl,2*2 ; Note 2nd level call
ld d,h
add hl,sp ; Point to 2nd string
ld e,(hl) ; Get length
ld c,e
inc hl
push hl
add hl,de ; Point to first string
ld e,(hl) ; Get length
ld b,e
inc hl
push hl
add hl,de ; Set return stack
push hl
pop iy ; Copy into reg IY
pop de ; Get 1st string
pop hl ; Get 2nd string
l09c4:
xor a ; Try zero length
cp b
jr z,l09cc
cp c ; Test on both
jr nz,l09d3
ld a,b
l09cc:
cp c
l09cd:
pop hl ; Get back callers
pop de
ld sp,iy ; Set new stack
push de ; Set 2nd kevel caller
jp (hl) ; Exit
l09d3:
ld a,(de)
cp (hl) ; Compare
jr nz,l09cd ; No match
inc hl
inc de
dec b
dec c
jr l09c4
;
; Verify value in reg HL in range 1..255
;
l09dd:
ld a,h ; Verify < 256
or a
jr nz,l09e4
ld a,l
or a ; Verify <> 0
ret nz
l09e4:
ld a,_StrIdx
jp l2029
;
; Function ADD:real
; ENTRY Regs (HL,DE,BC) hold 1st number
; Regs (HL,DE,BC)' hold 2nd number
; EXIT Regs (HL,DE,BC) hold sum
;
l09e9:
call l0a0d ; Add
l09ec:
ret nc ; Check result
ld a,_FLPovfl
jp l2027 ; Set error and abort
;
; Function SUBTRACT:real
; ENTRY Regs (HL,DE,BC) hold 1st number
; Regs (HL,DE,BC)' hold 2nd number
; EXIT Regs (HL,DE,BC) hold difference
;
l09f2:
call l0a81 ; Subtract
jr l09ec ; Check result
;
; Function SQR(real):real
; ENTRY Regs (HL,DE,BC) hold number
; EXIT Regs (HL,DE,BC) hold square
;
l09f7:
call l0fac ; Copy number, then multiply
;
; Function MULTIPLY:real
; ENTRY Regs (HL,DE,BC) hold multiplicand
; Regs (HL,DE,BC)' hold multiplier
; EXIT Regs (HL,DE,BC) hold product
;
l09fa:
call l0a97 ; Multiply
jr l09ec ; Check result
;
; Function DIVIDE:real
; ENTRY Regs (HL,DE,BC) hold 1st dividend
; Regs (HL,DE,BC)' hold 2nd divisor
; EXIT Regs (HL,DE,BC) hold quotient
;
l09ff:
exx ; Get divisor
ld a,l
or a ; Verify not zero
exx
l0a03:
ld a,_DivZero
jp z,l2027 ; Error if division by zero
call l0af5 ; Divide
jr l09ec ; Check result
;
; Add reals
; ENTRY Regs (HL,DE,BC) hold 1st number
; Regs (HL,DE,BC)' hold 2nd number
; EXIT Regs (HL,DE,BC) hold sum
; Carry set on overflow
;
l0a0d:
exx
bit sgn.bit,b ; Test sign of 2nd number
exx
jp nz,l0a88 ; Subtract if less 0
l0a14:
exx
ld a,l ; Test 2nd number zero
or a
exx
ret z ; Ok, result is the 1st number
exx
push bc ; Save 1st number
push de
push hl
exx
ld a,l
or a ; Test 1st number zero
jr nz,l0a27 ; Nope
exx
res sgn.bit,b ; Clear sign
jr l0a7b ; Get 2nd number as result
l0a27:
push bc
set sgn.bit,b ; Force bit set
xor a
ex af,af' ;'
exx
set sgn.bit,b
ld a,l
exx
sub l ; Test same exponents
jr z,l0a47 ; Yeap
jr nc,l0a3c
neg
ex af,af' ;'
dec a
ex af,af' ;'
exx
l0a3c:
call l0b7a ; Shift mantissa right
inc l ; Bump exponent
dec a
jr nz,l0a3c
ex af,af' ;'
jr z,l0a47
exx
l0a47:
pop af ; Get back mantissa MSB
and sign.bit ; Test sign
jr nz,l0a5b ; It's negative
call l0b92 ; Add mantissas
jr nc,l0a76 ; Test bit out
call l0b7b ; Rotate mantissa right
or a
inc l ; Fix exponent
jr nz,l0a76 ; Test underflow
scf
jr l0a7b
l0a5b:
call l0bc6 ; Compare mantissas
ccf
push af
jr z,l0a72 ; It's same
jr c,l0a65 ; It's less
exx
l0a65:
call l0bac ; Subtract mantissas
l0a68:
bit sgn.bit,b ; Test normalized
jr nz,l0a75 ; Yeap
call l0b86 ; Shift left
dec l
jr nz,l0a68
l0a72:
call l0b72 ; Zero result
l0a75:
pop af
l0a76:
jr c,l0a7a ; Test sign
res sgn.bit,b ; Reset if positive
l0a7a:
or a
l0a7b:
exx
pop hl
pop de
pop bc
exx
ret
;
; Subtract reals
; ENTRY Regs (HL,DE,BC) hold 1st number
; Regs (HL,DE,BC)' hold 2nd number
; EXIT Regs (HL,DE,BC) hold difference
; Carry set on overflow
;
l0a81:
exx
bit sgn.bit,b ; Test sign of 2nd number
exx
jp nz,l0a14 ; Add if less 0
l0a88:
call l0a8f ; Negate
call l0a14 ; Then add
ret c
;
; Negate real
; ENTRY Regs HL,DE,BC hold real number
; EXIT Sign changed if real > 0
;
l0a8f:
inc l ; Test exponent zero
dec l
ret z ; Exit if so
ld a,b
xor sign.bit ; Change sign bit
ld b,a
ret
;
; Multiply reals
; ENTRY Regs (HL,DE,BC) hold multiplicand
; Regs (HL,DE,BC)' hold multiplier
; EXIT Regs (HL,DE,BC) hold product
; Carry set on overflow
;
l0a97:
exx
ld a,l
or a ; Test zero multiplier
exx
jp z,l0b72 ; Return 0.0 if so
ld a,l
or a
ret z ; Return if multiplicand zero
exx
add a,l ; Add exponents
exx
call l0b4d ; Fix exponent
push bc ; Save number
push de
push hl
add ix,sp
call l0b72 ; Prepare result
exx
ld l,mant.len ; Set mantissa count
exx
l0ab3:
ld a,bit.len ; Set bit count
inc ix
ld l,(ix+0)
l0aba:
ex af,af' ;'
rr l ; Shift bit
jr nc,l0ac2
call l0b92 ; Add mantissa if bit out
l0ac2:
call l0b7b ; Rotate mantissa right
ex af,af' ;'
dec a ; Go thru all bits
jr nz,l0aba
exx
dec l
exx
jr nz,l0ab3
ld l,(ix-mant.len) ; Get byte back
bit sgn.bit,b ; Test sign
jr nz,l0ade
ex af,af' ;'
call l0b87 ; Get bit
inc l
dec l
jr z,l0ade
dec l
l0ade:
pop af ; Clean stack
pop af
pop af
l0ae1:
or a
l0ae2:
ex af,af' ;'
pop af
exx
pop bc
pop hl
exx
pop ix
res sgn.bit,b ; Reset hi bit
or b
ld b,a ; Insert sign
inc l
dec l
call z,l0b72 ; Clear if underflow
ex af,af' ;'
ret
;
; Divide reals
; ENTRY Regs (HL,DE,BC) hold 1st dividend
; Regs (HL,DE,BC)' hold 2nd divisor
; EXIT Regs (HL,DE,BC) hold quotient
; Carry set on overflow
;
l0af5:
ld a,l
or a ; Test zero divisor
ret z
exx
sub l ; Get resulting exponent
exx
ccf
call l0b4d ; Fix it
push hl
push hl
push hl
add ix,sp
exx
ld l,mant.len ; Get complete count
exx
ld a,bit.len ; Set bit count
l0b0a:
ex af,af' ;'
call l0bc6 ; Compare mantissas
jr c,l0b13
call l0bac ; Subtract mantissas
l0b13:
ccf
rl l
ex af,af' ;'
dec a ; Go thru the bits
jr nz,l0b26
ld (ix+mant.len),l ; Set result
dec ix
exx
dec l ; Go thru the mantissa
exx
jr z,l0b32 ; Total end
ld a,bit.len ; Reset bit count
l0b26:
call l0b86 ; Shift left
jr nc,l0b0a
ex af,af' ;'
call l0bac ; Subtract mantissas
or a
jr l0b13
l0b32:
call l0b86 ; Shift left
jr c,l0b3b
call l0bc6 ; Compare mantissas
ccf
l0b3b:
pop hl
pop de
pop bc
bit sgn.bit,b ; Test bit
jr nz,l0b47
call l0b87 ; Shift in
jr l0ae1
l0b47:
inc l ; Test ok
jr nz,l0ae1
scf
jr l0ae2
;
; Fix exponent
; ENTRY Accu and Carry reflect state of addition or
; subtraction of exponents
;
l0b4d:
jr c,l0b55 ; Test bit out
add a,exp.offset ; Add offset
jr c,l0b59 ; Test bit
jr l0b70
l0b55:
add a,exp.offset
jr c,l0b70
l0b59:
ld l,a ; Set new exponent
ex (sp),ix ; Get caller
exx
push hl
push bc
ld a,b
set sgn.bit,b ; Set bit
exx
xor b
and sign.bit ; Get result
push af
set sgn.bit,b ; Second, too
push ix ; Bring back caller
ld ix,0 ; Return IX=0
ret
l0b70:
pop hl
ret c
;
; Clear real number
; EXIT Regs (HL,DE,BC) hold zero
;
l0b72:
xor a
ld l,a ; Clear all involved bytes
ld b,a
ld c,a
ld d,a
ld e,a
ld h,a
ret
;
; Shift mantissa right
;
l0b7a:
or a ; Clear carry
;
; Rotate mantissa right
;
l0b7b:
rr b ; Shift 5 bytes right
rr c
rr d
rr e
rr h
ret
;
; Shift mantissa left
;
l0b86:
or a ; Clear carry
;
; Rotate mantissa left
;
l0b87:
rl h ; Shift 5 bytes left
rl e
rl d
rl c
rl b
ret
;
; Add mantissas
;
l0b92:
ld a,h ; Get 1st
exx ; Then second
add a,h ; Add
exx
ld h,a ; Into 1st
ld a,e
exx
adc a,e
exx
ld e,a
ld a,d
exx
adc a,d
exx
ld d,a
ld a,c
exx
adc a,c
exx
ld c,a
ld a,b
exx
adc a,b
exx
ld b,a
ret
;
; Subtract mantissas
;
l0bac:
ld a,h ; Get 1st
exx ; Then second
sub h ; Subtract
exx
ld h,a ; Into 1st
ld a,e
exx
sbc a,e
exx
ld e,a
ld a,d
exx
sbc a,d
exx
ld d,a
ld a,c
exx
sbc a,c
exx
ld c,a
ld a,b
exx
sbc a,b
exx
ld b,a
ret
;
; Compare mantissas
;
l0bc6:
ld a,b ; Get 1st
exx ; Then second
cp b ; Compare
exx
ret nz ; Exit if .NE. zero
ld a,c
exx
cp c
exx
ret nz
ld a,d
exx
cp d
exx
ret nz
ld a,e
exx
cp e
exx
ret nz
ld a,h
exx
cp h
exx
ret
;
; Compare two reals
; ENTRY 1st real in register set
; 2nd real in alternative set
; EXIT Carry flag set if 1st<2nd
; Zero flag set if 1st=2nd
;
l0bdf:
exx
ld a,b ; Get sign
exx
xor b ; Test same signs
jp p,l0be9 ; Yeap
ld a,b ; Get 1st sign
rla ; Calculate result
ret
l0be9:
bit sgn.bit,b ; Test 1st > 0
jr z,l0bf3 ; Yeap
call l0bf3 ; Compare
ret z
ccf
ret
l0bf3:
ld a,l ; Get exponent
exx
cp l ; Compare
exx
ret nz ; Not same
or a ; Test zero
ret z
jp l0bc6 ; Compare mantissas
;
; Function INT(real):real
;
l0bfd:
ld a,l
sub Exp.One ; Test >= 1
jp c,l0b72 ; Nope, return 0.0
inc a ; Fix count
cp mant.bits ; Test fraction
ret nc ; No, that's it
exx
push bc ; save 2nd
push de
push hl
ex af,af' ;'
call l0b72 ; Init result
ex af,af' ;'
l0c10:
scf
call l0b7b ; Rotate mantissa right
dec a
jr nz,l0c10
exx
ld a,h ; Mask result
exx
and h
exx
ld h,a
ld a,e
exx
and e
exx
ld e,a
ld a,d
exx
and d
exx
ld d,a
ld a,c
exx
and c
exx
ld c,a
ld a,b
exx
and b
exx
ld b,a
l0c31:
jp l0a7b
;
; Function FRAC(real):real
;
l0c34:
exx
push bc
push de
push hl
exx
call l0fac ; Copy number
exx
call l0bfd ; Get integer part
exx
call l0a81 ; Subtract from original number
jr l0c31
;
; Function SQRT(real):real
;
l0c46:
ld a,l ; Test zero operand
or a
ret z ; Ok, that's it
bit sgn.bit,b ; Verify operand >= 0
ld a,_NegSqrt
jp nz,l2027 ; Should be
call l0fac ; Copy number
ld a,l
add a,exp.offset
sra a ; Fix resulting exponent
add a,exp.offset
ld l,a
sub sqr.exp ; Fix exponent
push af
exx
l0c5f:
push bc
push de
push hl
call l0af5 ; Divide reals
call l0a0d ; Add reals
dec l ; Exponent - 1
push bc
push de
push hl
call l0a81 ; Subtract reals
ld a,l
pop hl
pop de
pop bc
exx
pop hl
pop de
pop bc
ex (sp),hl
cp h ; Test ready
ex (sp),hl
jr nc,l0c5f ; Loop on
pop af
exx
ret
;
; Function COS(real):real
;
l0c7f:
exx
call l0f8e ; Load constant PI
dec l ; Make 90 degrees
call l0a81 ; Subtract reals
;
; Function SIN(real):real
;
l0c87:
exx
call l0f8e ; Load constant PI
inc l ; Make 360 degrees
exx
ld a,l
cp sin.min ; Test underflow
ret c
push bc
res sgn.bit,b ; Clear sign
call l0bdf ; Compare against period
pop bc
jr c,l0ca3
call l0af5 ; Divide reals
call l0c34 ; Get fraction
call l0a97 ; Multiply reals
l0ca3:
bit sgn.bit,b ; Test sign
jr z,l0caa
call l0a0d ; Add reals
l0caa:
exx
dec l ; Make 180 degrees
exx
call l0bdf ; Test within 180 degrees
push af
jr c,l0cb6
call l0a81 ; Subtract reals
l0cb6:
exx
dec l ; Make 90 degrees
exx
call l0bdf ; Test within 90 degrees
jr c,l0cc3
exx
inc l ; Make 180 degrees
call l0a81 ; Subtract reals
l0cc3:
ld a,l
cp sin.min ; Test underflow
jr c,l0d03
exx
ld bc,02aaah ; Set 1/3
ld de,0aaaah
ld hl,0aa7fh
call l0a97 ; Multiply reals (Divide by 3)
push ix
ld ix,l0d0d-Real.Len
ld a,Trg.Len
call l0f34 ; Do the TAYLOR loop
pop ix
call l0fac ; Copy number
call l0a97 ; Multiply reals
call l0a97 ; Multiply reals
push bc
push de
push hl
exx
call l0fac ; Copy number
dec l ; Divide by 4
dec l
exx
dec l ; Divide by 2
call l0a0d ; Add reals
exx
pop hl
pop de
pop bc
exx
call l0a81 ; Subtract reals
inc l ; Multiply by 4
inc l
l0d03:
pop af
inc l ; Test zero
dec l
ret z
ret c ; Check sign
ld a,b
xor sign.bit ; Toggle it
ld b,a
ret
;
; Taylor series for SINE and COSINE
;
l0d0d:
db 067h,0aah,03fh,02bh,032h,0d7h ; -1/11!
db 06eh,0b6h,02ah,01dh,0efh,038h ; 1/9!
db 074h,00dh,0d0h,000h,00dh,0d0h ; -1/7!
db 07ah,088h,088h,088h,088h,008h ; 1/5!
db 07eh,0abh,0aah,0aah,0aah,0aah ; -1/3!
Trg.Len equ ($-l0d0d)/Real.Len
;
; Function LN(real):real
;
l0d2b:
inc l
dec l ; Check zero
ld a,_LNerr
jp z,l2027 ; Error if so
bit sgn.bit,b
jp nz,l2027 ; If negative, too
exx
call l0f98 ; Load constant SQRT(2)
exx
ld a,l
ld l,Exp.One ; Fix exponent
sub l
push af
call l0af5 ; Divide reals
exx
call l0f86 ; Load constant 1.0
exx
call l0a81 ; Subtract reals
push bc
push de
push hl
exx
inc l ; Number times 2
call l0a0d ; Add reals
exx
pop hl
pop de
pop bc
call l0af5 ; Divide reals
push ix
ld ix,l0d92-Real.Len
ld a,LN.len
call l0f34 ; Do the TAYLOR loop
pop ix
inc l ; Number times 2
exx
call l0fa2 ; Load constant LN(2)
dec l ; Halve it
exx
call l0a0d ; Add reals
pop af
push bc
push de
push hl
ld l,a
ld h,0
jr nc,l0d7c
dec h ; Set -1
l0d7c:
call l1008 ; Convert to real
exx
inc l ; Number times 2
call l0a97 ; Multiply reals
exx
pop hl
pop de
pop bc
call l0a0d ; Add reals
ld a,l
cp ln.min ; Test underflow
jp c,l0b72 ; Return 0.0 if so
ret
;
; Taylor series for Natural Logarithm
;
l0d92:
db 07dh,08ah,09dh,0d8h,089h,01dh ; 1/13
db 07dh,0e9h,0a2h,08bh,02eh,03ah ; 1/11
db 07dh,08eh,0e3h,038h,08eh,063h ; 1/9
db 07eh,049h,092h,024h,049h,012h ; 1/7
db 07eh,0cdh,0cch,0cch,0cch,04ch ; 1/5
db 07fh,0abh,0aah,0aah,0aah,02ah ; 1/3
LN.len equ ($-l0d92)/Real.Len
;
; Function EXP(real):real
;
l0db6:
exx
call l0fa2 ; Load constant LN(2)
exx
or a
bit sgn.bit,b
push af ; Save sign
res sgn.bit,b ; Clear it
call l0af5 ; Divide reals
ld a,l
cp exp.max ; Test overflow
jr nc,l0e10
push bc
push de
push hl
inc l ; Times 2
call l0fd0 ; Get integer
push hl
srl h ; Divide by 2
rr l
ld a,l
pop hl
push af
call l1008 ; Back to real
inc l ; Test zero
dec l
jr z,l0de0
dec l ; Fix if not
l0de0:
exx
pop af
pop hl
pop de
pop bc
push af
call l0a81 ; Subtract reals
push ix
ld ix,l0e16-Real.Len
ld a,EXP.Len
call l0f49 ; Do the TAYLOR loop
pop ix
pop af
jr nc,l0e03
push af
exx
call l0f98 ; Load constant SQRT(2)
exx
call l0a97 ; Multiply reals
pop af
l0e03:
add a,l ; Build resulting exponent
ld l,a
jr c,l0e10 ; Overflow
pop af ; Test sign
ret z
exx
call l0f86 ; Load constant 1.0
jp l0af5 ; Divide reals (1/number)
l0e10:
pop hl
ld a,_FLPovfl ; Error
jp l2027
;
; Taylor series for natural EXPonetiation
;
l0e16:
db 06dh,02eh,01dh,011h,060h,031h ; 1.3215 E-6
db 070h,046h,02ch,0feh,0e5h,07fh ; 1.5252 E-5
db 074h,036h,07ch,089h,084h,021h ; 1.5403 E-4
db 077h,053h,03ch,0ffh,0c3h,02eh ; 1.3333 E-3
db 07ah,0d2h,07dh,05bh,095h,01dh ; 9.6181 E-3
db 07ch,025h,0b8h,046h,058h,063h ; 5.5504 E-2
db 07eh,016h,0fch,0efh,0fdh,075h ; 2.4022 E-1
db 080h,0d2h,0f7h,017h,072h,031h ; 6.9314 E-1
EXP.Len equ ($-l0e16)/Real.Len
;
; Function ARCTAN(real):real
;
l0e46:
ld a,l
or a ; Test zero
ret z
push ix
exx
call l0f86 ; Load constant 1.0
exx
xor a
bit sgn.bit,b ; Test sign
jr z,l0e58
inc a
res sgn.bit,b ; Make absolute
l0e58:
push af
call l0bdf ; Compare against 1.0
jr c,l0e66
exx
call l0af5 ; Divide reals (1/number)
pop af
set sgn.bit,a ; Indicate reverse
push af
l0e66:
exx
ld bc,006cfh ; Load 0.13165
ld de,0e98eh
ld hl,04a7eh
exx
call l0bdf ; Compare reals
jr nc,l0e7b
call l0f2e ; Build TAYLOR series
jr l0eca
l0e7b:
ld ix,l0ee0-3*Real.Len
ld a,2 ; Set loop
l0e81:
ex af,af' ;'
exx
ld de,3*Real.Len
add ix,de
call l0f73 ; Get value from table
exx
call l0bdf ; Compare reals
jr c,l0e9c
ex af,af' ;'
dec a ; Go thru the loop
jr nz,l0e81
exx
ld de,2*Real.Len
add ix,de ; Fix table
exx
l0e9c:
exx
call l0f6e ; Get next from table
set sgn.bit,b ; Make negative
call l0a0d ; Add reals
push bc
push de
push hl
call l0f73 ; Get value back
call l0a97 ; Multiply reals
exx
call l0f86 ; Load constant 1.0
call l0a0d ; Add reals
exx
pop hl
pop de
pop bc
call l0af5 ; Divide reals
push ix
call l0f2e ; Do TAYLOR
pop ix
exx
call l0f6e ; Get from table
call l0a0d ; Add reals
l0eca:
pop af
rla ; Get sign bit
jr nc,l0ed8
push af
exx
call l0f8e ; Load constant PI
dec l ; Make 90 degrees
call l0a81 ; Subtract reals
pop af
l0ed8:
pop ix
bit 1,a ; Test operand sign
ret z
set sgn.bit,b ; Set negative
ret
;
; 2nd Taylor series for ARCTangent
;
l0ee0:
db 07fh,0e7h,0cfh,0cch,013h,054h ; 4.1421 E-1
db 07fh,0f6h,0f4h,0a2h,030h,009h ; 2.6794 E-1
db 07fh,06ah,0c1h,091h,00ah,006h ; 2.6179 E-1
db 080h,0b5h,09eh,08ah,06fh,044h ; 7.6732 E-1
db 080h,082h,02ch,03ah,0cdh,013h ; 5.7735 E-1
db 080h,06ah,0c1h,091h,00ah,006h ; 5.2359 E-1
db 081h,000h,000h,000h,000h,000h ; 1.0000
db 080h,021h,0a2h,0dah,00fh,049h ; 7.8539 E-1
;
; Taylor series for ARCTangent
;
l0f10:
db 07dh,0e8h,0a2h,08bh,02eh,0bah ; -1/11
db 07dh,08eh,0e3h,038h,08eh,063h ; 1/9
db 07eh,049h,092h,024h,049h,092h ; -1/7
db 07eh,0cdh,0cch,0cch,0cch,04ch ; 1/5
db 07fh,0abh,0aah,0aah,0aah,0aah ; -1/3
AT.Len equ ($-l0f10)/Real.Len
;
; Perform TAYLOR series
; Calculate SERIES(x^2)*x
;
l0f2e:
ld ix,l0f10-Real.Len
ld a,AT.Len
l0f34:
push bc
push de
push hl
push af
call l0fac ; Copy number
call l0a97 ; Multiply reals [^2]
pop af
call l0f49 ; Do the TAYLOR loop
exx
pop hl
pop de
pop bc
jp l0a97 ; Multiply reals
;
; The TAYLOR series loop
; ENTRY Reg IX points to table
; Accu holds loop count
; Calculate : 1-(1/3!)x+..+/-..-(1/11!)x^8
;
l0f49:
push af
exx
call l0f6e ; Load from table
jr l0f60 ; Skip addition this time
l0f50:
push af
exx
push bc
push de
push hl
call l0f6e ; Get next value from table
call l0a0d ; Add reals
exx
pop hl
pop de
pop bc
exx
l0f60:
call l0a97 ; Multiply reals
pop af
dec a ; Test done
jr nz,l0f50 ; Nope
exx
call l0f86 ; Load constant 1.0
jp l0a0d ; Add reals
;
; Load next real from table
; ENTRY Reg IX points to table
; EXIT Regs (HL,DE,BC) hold real
;
l0f6e:
ld de,Real.Len
add ix,de ; Point to nexr
;
; Load real from table
; ENTRY Reg IX points to table
; EXIT Regs (HL,DE,BC) hold real
;
l0f73:
ld l,(ix+0) ; Get exponent
ld h,(ix+1) ; Mantissa LSB
ld e,(ix+2)
ld d,(ix+3)
ld c,(ix+4)
ld b,(ix+5) ; Mantissa MSB
ret
;
; Load constant 1.0
;
l0f86:
ld hl,Exp.One ; Load 6 bytes 2^0
ld b,h
ld c,h
ld d,h
ld e,h
ret
;
; Load constant PI=3.141592654
;
l0f8e:
ld bc,0490fh ; Load 6 bytes
ld de,0daa2h
ld hl,02182h
ret
;
; Load constant SQRT (2)=1.414213562
;
l0f98:
ld bc,03504h ; Load 6 bytes
ld de,0f333h
ld hl,0fa81h
ret
;
; Load constant LN (2)=0.693147181
;
l0fa2:
ld bc,03172h ; Load 6 bytes
ld de,017f7h
ld hl,0d280h
ret
;
; Copy real number
; ENTRY Regs (HL,DE,BC) hold number
; EXIT Number copied to alternating regs (HL,DE,BC)'
;
l0fac:
push bc ; Push onto stack
push de
push hl
exx ; Copy into alternate registers
pop hl ; Pop back
pop de
pop bc
ret
;
; Function RANDOM:real;
; EXIT Regs (HL,DE,BC) hold number
;
l0fb4:
call l0792 ; Get random value
ld hl,exp.offset ; Init exponent and count
ld a,mant.bits-bit.len
l0fbc:
bit sgn.bit,b ; Test MSB set
jr nz,l0fcd
sla e ; Shift left if not
rl d
rl c
rl b
dec l ; Count down exponent
dec a
jr nz,l0fbc
ld l,a
l0fcd:
res sgn.bit,b ; .. make 1.0> x >=0.0
ret
;
; Function ROUND(real):integer
;
l0fd0:
bit sgn.bit,b ; Attache sign
exx
call l0f86 ; Load constant 1.0
jr z,l0fda ; Test < 0
set sgn.bit,b ; make constant -1.0
l0fda:
dec l ; Set +-0.5
call l0a0d ; Add reals
;
; Function TRUNC(real):integer
;
l0fde:
or a
bit sgn.bit,l ; Test exponent < 0
jr z,l0fff ; Return zero if so
bit sgn.bit,b ; Mark sign
ex af,af' ;'
set sgn.bit,b ; Set bit
l0fe8:
ld a,int.max
cp l
jr c,l1003 ; Test overflow
jr z,l0ff5 ; Or end of conversion
call l0b7a ; Shift mantissa right
inc l ; Bump exponent
jr l0fe8
l0ff5:
call l0b7a ; Shift mantissa right
ex af,af' ;'
ld h,b ; Get result
ld l,c
ret z ; End if > 0
jp l0783 ; Negate
l0fff:
ld hl,0 ; Return 0
ret
l1003:
ld a,_TruncOvl
jp l2027 ; Set error
;
; Convert integer to floating point
; ENTRY Reg HL holds signed integer
; EXIT Regs (HL,DE,BC) hold real
;
; NOTE: ON INTEGER 8000H AND ONLY ON THIS NUMBER
; THIS ROUTINE WILL LOOP FOREVER !!!!!!!!
;
l1008:
ld a,h ; Test Zero
or l
jp z,l0b72 ; Set 0.0 if so
bit sgn.bit,h ; Test sign
ex af,af' ;'
call l0780 ; Make number positive
ld a,int.max+1 ; Init exponent
l1015:
add hl,hl ; Shift mantissa
dec a ; Fix exponent
bit sgn.bit,h ; Test ready
jr z,l1015 ; Nope, wait for bit
ld b,h ; Get into hi part of mantissa
ld c,l
ld de,0 ; Clear lo part
ld h,d
ld l,a
ex af,af' ;' ; Test sign
ret nz
res sgn.bit,b ; Set > 0
ret
;
; Convert real to formatted ASCII string
; ENTRY Reg HL holds fix comma places (-1 on none)
; Reg DE holds decimal places
; Regs (HL,BC,DE)' hold real number
; Reg IX points to ASCII buffer
;
l1027:
call l04c8 ; Get fix comma places
ex de,hl
ld e,0
jr c,l1033 ; Integer was < 0, no places
cp real.dig+1 ; Test max digits
jr c,l104b
l1033:
dec e
call l04c8 ; Get decimal places
exx
bit sgn.bit,b ; Test sign
exx
ld d,real.field ; Init field size
jr z,l1040
inc d ; Fix for sign < 0.0
l1040:
sub d ; Test against field length
jr nc,l1044
xor a
l1044:
cp real.field+2 ; Test max
jr c,l104a
ld a,real.field+2
l104a:
inc a
l104b:
ld d,a
push de
exx
ld iy,Number ;number ;???
push ix
call l10eb ; Prepare conversion
pop ix
pop de
ld c,a ; Save result exponent
ld a,d
inc a
bit sgn.bit,e ; Test sign
jr nz,l1071 ; < 0
add a,c ; Fix exponent
jp p,l106b
ld (iy),0 ; Clear entry
jr l1076
l106b:
cp real.ASCII ; Test decimal places
jr c,l1071
ld a,real.ASCII-1 ; Truncate it
l1071:
push de
call l1180 ; Normalize ASCII
pop de
l1076:
bit sgn.bit,b ; Test sign
jr z,l107f
ld a,'-'
call l10e5 ; Set sign
l107f:
bit sgn.bit,e ; Test sign
jr z,l1086
ld h,c ; Unpack
ld c,0
l1086:
bit sgn.bit,c ; Test sign
jr z,l108f
call l10e3 ; Set 0
jr l1096
l108f:
call l10d9 ; Copy ASCII
dec c ; Bump down
jp p,l108f
l1096:
ld a,d ; Test mantissa
or a
jr z,l10b1 ; None
ld a,'.'
call l10e5 ; Set decimal dot
l109f:
inc c ; Fix exponent
jr z,l10a8
call l10e3 ; Set 0
dec d
jr nz,l109f
l10a8:
dec d
jp m,l10b1
call l10d9 ; Copy ASCII
jr l10a8
l10b1:
bit sgn.bit,e ; Test exponent
ret z ; Nope
ld a,'E'
call l10e5 ; Set 'E'xponent
ld a,'+'
bit sgn.bit,h ; Test bit
jr z,l10c5
ld a,h
neg ; Make exponent > 0
ld h,a
ld a,'-'
l10c5:
call l10e5 ; Store sign of exponent
ld a,h ; Get exponent
ld b,'0'-1 ; Init HI
l10cb:
inc b ; Fix result
sub 10 ; Divide by 10
jr nc,l10cb
add a,'9'+1 ; Make remainder ASCII
ld (ix),b ; save HI
inc ix
jr l10e5 ; Store LO
;
; Copy from buffer, set 0 if end
;
l10d9:
ld a,(iy) ; Get number
inc iy
or a ; Test end
jr nz,l10e5 ; Nope
dec iy ; Fix for zero storage
;
; Store ASCII zero into number
;
l10e3:
ld a,'0' ; Set zero
;
; Store ASCII into number
;
l10e5:
ld (ix),a ; Store number
inc ix ; Update pointer
ret
;
; Prepare ASCII for real to formatted ASCII conversion
; ENTRY Reg IY points to ASXII buffer
; Regs (HL,BC,DE) hold real number
; EXIT Buffer pre-filled
; Accu holds exponent equivalent
;
l10eb:
push iy ; save buffer
inc l ; Test zero number
dec l
jr nz,l10ff
ld b,real.ASCII ; Set length
l10f3:
ld (iy),'0' ; Clear ASCII number
inc iy
djnz l10f3
xor a
jp l117d
l10ff:
push bc ; Save sign
res sgn.bit,b ; Reset sign
ld a,l
exx
sub exp.offset ; Strip off offset
ld l,a
sbc a,a ; Expand to signed 16 bit
ld h,a
ld de,ExpFix
call l06f5 ; HL:=HL*DE
ld de,10 / 2
add hl,de ; Gix exponent
ld a,h
cp ExpRange ; Test range
jr nz,l1119
inc a ; Fix result
l1119:
ld (iy),a ; Store into buffer
neg
call l1240
ld a,l
cp Exp.One ; Test exponent
jr nc,l112c
call l12b3 ; Fix mantissa
dec (iy) ; Fix exponent
l112c:
set sgn.bit,b ; Set bit
ld a,exp.offset+4
sub l ; Test exponent
ld l,0
jr z,l113d
l1135:
call l0b7a ; Shift mantissa right
rr l
dec a
jr nz,l1135
l113d:
ld a,(iy) ; Get exponent
push af
ld a,real.ASCII ; Set count
l1143:
ex af,af'
ld a,b ; Get MSB
rra ; Isolate hi
rra
rra
rra
and LoMask ; Mask bits
add a,'0' ; Make ASCII
ld (iy),a
inc iy
ld a,b
and LoMask
ld b,a
push bc
push de
push hl
sla l
call l0b87 ; Rotate mantissa left *2
sla l
call l0b87 ; * 4
ex de,hl
ex (sp),hl
add hl,de ; * 5
pop de
ex (sp),hl
adc hl,de
ex de,hl
pop hl
ex (sp),hl
adc hl,bc
ld b,h
ld c,l
pop hl
sla l
call l0b87 ; *10
ex af,af'
dec a
jr nz,l1143
pop af
pop bc
l117d:
pop iy
ret
;
; Normalize ASCII number
; ENTRY Accu holds length of number
;
l1180:
push iy
pop hl ; Copy buffer
ld e,a
ld d,0
add hl,de
ld a,(hl) ; Get last digit
ld (hl),0
cp '5' ; Test to be normalized
ret c ; Nope
l118d:
dec e ; Count down
jp m,l119c
dec hl ; Get previous
ld a,(hl)
inc a ; Advance digit
ld (hl),a
cp '9'+1 ; Test in range
ret c ; Yeap
ld (hl),0 ; Clear this one
jr l118d
l119c:
ld (hl),'1' ; Set carry
inc hl
ld (hl),0 ; Clear next
inc c
ret
;
; Convert ASCII string to Floating Point number
; ENTRY Reg IX points to ASCII number
; EXIT Regs HL,DE,BC hold real
; Carry set indicates conversion error
;
cnv_flp:
exx
ld bc,0 ; Reset flags
exx
call l0b72 ; Init 0.0
l11ab:
ld a,(ix) ; Get character
call doupcase ; Convert to upper case
cp '.' ; Test decimal point
jr nz,l11c1
exx
bit dot.bit,b ; Test already selected
scf
ret nz ; Error if so
set dot.bit,b ; Indicate dot
exx
l11bd:
inc ix ; Skip character
jr l11ab ; Get next
l11c1:
cp 'E' ; Test exponent
jr z,l11e6 ; Yeap, process it
call l1239 ; Test digit
jr nc,l121e ; Nope
ex af,af'
call l12b3 ; Convert mantissa
ret c ; Error
ex af,af'
exx
push bc
ld l,a ; Build integer
ld h,0
call l1008 ; Convert to floating point
call l09e9 ; Add reals
exx
pop bc
ret c ; End if overflow
bit dot.bit,b ; Test decimal point
jr z,l11e3
dec c ; Fix length if so
l11e3:
exx
jr l11bd
;
; Found 'E'xponent
;
l11e6:
call l121e ; Fix mantissa
ret c ; Overflow
exx
set exp.bit,b ; Set bit
inc ix
ld a,(ix)
cp '+' ; Test any sign
jr z,l11fc ; Skip plus
cp '-'
jr nz,l11fe
set exps.bit,b ; Indicate negative exponent
l11fc:
inc ix
l11fe:
call l1236 ; Get 1st digit
ccf
ret c ; Invalid
ld c,a
inc ix
call l1236 ; Get 2nd digit
jr nc,l1215 ; Only one
inc ix
ld d,a
ld a,c ; Get first one - it's tens
add a,a ; * 2
add a,a ; * 4
add a,c ; * 5
add a,a ; *10
add a,d ; Insert 2nd
ld c,a
l1215:
bit exps.bit,b ; Test exponent < 0
jr z,l121d ; Nope
ld a,c
neg ; Change it if so
ld c,a
l121d:
exx
l121e:
exx
ld a,c ; Get exponent
add a,exp.offset ; Set offset
cp 05ah ; Check range
ret c ; Underflow
cp 0a6h
ccf
ret c ; Overflow
push bc
push ix
ld a,c
call l1240 ; Fix exponent
pop ix
exx
pop bc ; Fix stack
exx
ret
;
; Get character and test if digit
; ENTRY Reg IX points to character
; EXIT Accu holds character
; Carry reset if in range
;
l1236:
ld a,(ix) ; Get character
;
; Test character a digit - C set if so
; ENTRY Accu holds character
; EXIT Carry reset if in range
;
l1239:
sub '0' ; Strip off offset
ccf
ret nc ; Out of range
cp 9+1
ret
;
; Fix exponent for real to ASCII conversion
; ENTRY Accu holds exponent equivalent
; EXIT Real fixed
;
l1240:
push af ; Save exponent
or a ; Test sign
jp p,l1247
neg ; Make >0
l1247:
push af
srl a ; Shift
srl a
inc a ; Then fix
ld hl,-Real.Len ; Init index
ld de,Real.Len
l1253:
add hl,de ; Fix index
dec a
jr nz,l1253
ex de,hl
ld ix,l1277 ; Point to table
add ix,de
call l0f73 ; Get number from table
pop af
and 11b ; Get MOD 4
jr z,l126e
l1266:
push af
call l12b3 ; Fix mantissa
pop af
dec a
jr nz,l1266
l126e:
pop af ; Get back exponent
or a
jp p,l0a97 ; Multiply reals if > 0
exx
jp l0af5 ; Divide reals if < 0
;
; Fix up table
;
l1277:
db 081h,000h,000h,000h,000h,000h ; 1 E 0
db 08eh,000h,000h,000h,040h,01ch ; 1 E 4
db 09bh,000h,000h,020h,0bch,03eh ; 1 E 8
db 0a8h,000h,010h,0a5h,0d4h,068h ; 1 E12
db 0b6h,004h,0bfh,0c9h,01bh,00eh ; 1 E16
db 0c3h,0ach,0c5h,0ebh,078h,02dh ; 1 E20
db 0d0h,0cdh,0ceh,01bh,0c2h,053h ; 1 E24
db 0deh,0f9h,078h,039h,03fh,001h ; 1 E28
db 0ebh,02bh,0a8h,0adh,0c5h,01dh ; 1 E32
db 0f8h,0c9h,07bh,0ceh,097h,040h ; 1 E36
;
; Fix mantissa for real to ASCII conversion
; ENTRY Regs (BC,DE,HL) hold real
; EXIT Real fixed
;
l12b3:
ld a,l ; Test exponent
or a
ret z ; Zero
set _MB,b ; Set bit
push bc
push de
ld a,h
call l0b7a ; Shift mantissa right
call l0b7a ; Two places
add a,h ; Add LSB
ld h,a
ex (sp),hl ; Get middle part
adc hl,de ; Add it
ex de,hl
pop hl
ex (sp),hl
adc hl,bc ; Same for hi part
ld b,h ; Copy to high
ld c,l
pop hl ; Get back old hi
jr nc,l12d6
call l0b7b ; Rotate mantissa right
inc l ; Fix exponent
scf
ret z
l12d6:
ld a,l
add a,3 ; Fix exponent
ld l,a
res _MB,b ; Clear bit
ret
;
; Test sets not equal (<>)
; ENTRY Both sets on stack
; EXIT Reg HL holds boolean result
;
l12dd:
ld c,_TRUE ; Set flag
jr l12e3 ; Compare
;
; Test sets equal (=)
; ENTRY Both sets on stack
; EXIT Reg HL holds boolean result
;
l12e1:
ld c,FALSE
l12e3:
call l133f ; Get sets
l12e6:
ld a,(de)
cp (hl) ; Compare
jr nz,l12f2 ; Not equal
inc hl
inc de
djnz l12e6
ld a,c
xor _TRUE ; Zoggle flag if equal
ld c,a
l12f2:
ld hl,2*set.len
add hl,sp ; Fix stack
ld sp,hl
ld l,c ; Get state
ld h,0
jp (ix) ; Exit
;
; Test two sets included (1st in 2nd, <=)
; ENTRY Both sets on stack
; EXIT Reg HL holds boolean result
;
l12fc:
ld c,_TRUE ; Set flag
jr l1302
;
; Test two sets included (2nd in 1st, >=)
; ENTRY Both sets on stack
; EXIT Reg HL holds boolean result
;
l1300:
ld c,FALSE
l1302:
call l133f ; Get sets
dec c ; Test comparision mode
jr nz,l1309
ex de,hl
l1309:
ld c,FALSE
l130b:
ld a,(de)
or (hl) ; Combine
cp (hl) ; Compare
jr nz,l12f2
inc hl
inc de
djnz l130b
ld c,_TRUE ; Return TRUE
jr l12f2
;
; Combine two sets (add, +)
; ENTRY Both sets on stack
; EXIT Combined set on stack
;
l1318:
call l133f ; Get sets
l131b:
ld a,(de)
or (hl) ; Combine sets
ld (hl),a
inc hl
inc de
djnz l131b
l1322:
ex de,hl
ld sp,hl
jp (ix)
;
; Combine two sets (subtract, -)
; ENTRY Both sets on stack
; EXIT Combined set on stack
;
l1326:
call l133f ; Get sets
l1329:
ld a,(de)
cpl ; Complement
and (hl) ; Mask bits
ld (hl),a
inc hl
inc de
djnz l1329
jr l1322
;
; Combine two sets (intersection, *)
; ENTRY Both sets on stack
; EXIT Combined set on stack
;
l1333:
call l133f ; Get sets
l1336:
ld a,(de)
and (hl) ; Mask
ld (hl),a
inc hl
inc de
djnz l1336
jr l1322
;
; Get addresses of sets
; ENTRY Both sets on stack
; EXIT Regs HL and DE point to sets
; Reg IX holds caller address
; Reg B holds set length
;
l133f:
pop iy ; Get last caller
pop ix ; Get caller before last one
ld hl,0
add hl,sp
ex de,hl ; Get 1st set
ld hl,set.len
ld b,l ; Get length
add hl,sp ; Get 2nd set
jp (iy) ; Return
;
; Test element in set (IN)
; ENTRY Both sets on stack
; EXIT Reg HL holds boolean result
;
l134f:
pop ix ; Get caller
ld hl,set.len+1
add hl,sp ; Get pointer to set
ld a,(hl)
or a ; Test any set
jr z,l135c
xor a
jr l1362 ; Force FALSE
l135c:
dec hl
ld b,(hl)
call l05ba ; Get bit state
and (hl)
l1362:
ld hl,set.len+2
add hl,sp
ld sp,hl ; Set return stack
ld hl,FALSE ; Init FALSE
jr z,l136d ; Test result
inc hl ; Set TRUE
l136d:
jp (ix)
;
; Procedure ASSIGN(file,filename)
; ENTRY Filenname as string on stack
; FIB followed string
;
; Assign text file
;
l136f:
db skip ; Set non zero
;
; Assign (un)typed file
;
l1370:
xor a ; Set zero
ld (l00e8),a ;ok ;FIXME ; Put into mode
pop iy ; Get back caller
ld hl,(l00d2) ;ok ;FIXME ; Get top of memory
ld b,16 ; And max length
call l05e2 ; Assign string from stack
xor a
ld (de),a ; Close it
pop hl ; Fetch FIB
ld (l00e2),hl ;ok ;FIXME ; Put into device
push iy ; Bring back caller
ld a,h ; Verify not standard but file
or a
jr nz,l1390
ld a,_StdAssErr ; Set illegal FIB
ld (l00d0),a ;ok ;FIXME
ret
l1390:
ld a,(l00e8) ;ok ;FIXME ; Get back mode
or a ; Test text file
jr z,l13a0 ; Nope
call l13b6 ; Find standard device
jr nz,l13a0 ; Nope
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
ld (hl),a ; Set flag
ret
l13a0:
call l03f2 ; Parse file
ld hl,(l00e2) ;ok ;FIXME
ld (hl),0
ld de,FIB.FCB
add hl,de ; Point to FCB part
ex de,hl
ld hl,l005c
ld bc,FCBlen
ldir ; move FCB to FIB
ret
;
; Find standard IO device
; ENTRY TOPRAM filled with device string
; EXIT Zero flag set if device found
; Accu holds FIB flag if so
;
l13b6:
ld b,Std.Len ; Init length
ld hl,l13e6 ; Get table address
l13bb:
push bc
push hl
ld b,Std.Itm-1 ; Set length of one item
ld de,(l00d2) ;ok ;FIXME ; Get top of memory
l13c3:
inc de
ld a,(de)
cp ' ' ; Skip leading blanks
jr z,l13c3
l13c9:
ld a,(de) ; Get character
call doupcase ; Convert to upper case
sub (hl) ; Compare
jr z,l13da ; Maybe a hit
pop hl
pop bc
ld de,Std.Itm
add hl,de ; Point to next entry
djnz l13bb ; Try more
or a
ret
l13da:
inc hl
inc de
djnz l13c9 ; Loop until all found
pop bc
pop bc
ld a,(de)
cp ':' ; Verify standard device
ret nz
ld a,(hl) ; Get flag if so
ret
;
; Standard character I/O devices
;
l13e6:
db 'CON'
db 11000001b ; Input output for CON
Std.Itm equ $-l13e6
db 'TRM'
db 11000001b ; Input output for TRM
db 'KBD'
db 10000010b ; Input for KBD
db 'LST'
db 01000011b ; Output for LST
db 'AUX'
db 11000100b ; Input output for AUX
db 'USR'
db 11000101b ; Input output for USR
Std.Len equ ($-l13e6) / Std.Itm
;
; Prepare files
; ENTRY Reg HL points to FIB
;
; Procedure REWRITE(text_file)
;
l13fe:
db skip
;
; Procedure RESET(text_file)
;
l13ff:
xor a
ld (l00e8),a ;ok ;FIXME ; Set mode (0=RESET)
call l1469 ; Close open file
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
ret nz ; End if so
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
res wr.bit,(hl) ; Reset write flag
ld a,(hl)
and FIBtype ; Get type
ret nz ; Exit on standard device
call l1430 ; Prepare file operation
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
ret nz ; Exit if so
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
ld a,(l00e8) ;ok ;FIXME ; Get file mode
or a ; Test RESET
ld bc,RecLng*256+_.in
jr z,l142b ; Yeap
ld bc,0*256+_.out
l142b:
ld (hl),c ; Set flag
inc hl
inc hl
ld (hl),b ; Set buffer pointer
ret
;
; Prepare file operation for current FIB
;
l1430:
call l145a ; Clear FCB of this FIB
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
ld a,(l00e8) ;ok ;FIXME ; Get file mode
or a ; Test RESET
ld bc,_NoFile*256+_open
jr z,l144e ; Yeap, go open file
push de
ld c,_delete
call BDOS ; Delete file before rewrite
pop de
ld bc,_DirFull*256+_make
l144e:
push bc
call BDOS ; Now open or make file
pop bc
;inc a ; Test success
;ret nz ; Yeap
or a
ret z
ld a,b
ld (l00d0),a ;ok ;FIXME ; Set error if not
ret
;
; Clear FCB of current FIB
;
l145a:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld de,FIB.FCB+_ex
add hl,de ; Point to EX filed
ld b,FCBlen-_ex ; Set length
l1463:
ld (hl),0 ; Clear it
inc hl
djnz l1463
ret
;
; Close text file
;
; Procedure CLOSE(text_file)
;
; ENTRY Reg HL holds FIB
;
l1469:
ld (l00e2),hl ;ok ;FIXME ; Save FIB for current device
ld a,(hl)
and FIBtype ; Get type
ret nz ; Exit if not a file
bit out.bit,(hl) ; Test output
jr z,l147e ; Skip if not
ld a,eof
call l16c6 ; Close file by EOF
call l170c ; Then flash buffer
jr l1481
l147e:
bit in.bit,(hl) ; Test input
ret z ; Nope, end
l1481:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
push hl
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
ld c,_close
call BDOS ; Close file
pop hl
inc a ; Test success
jr nz,l1498 ; Yeap
ld a,_NoClose
ld (l00d0),a ;ok ;FIXME ; Set error
l1498:
ld (hl),0 ; Reset FIB flag
ret
;
; Set standard device
;
l149b:
ex (sp),hl
ld (l00e4),hl ;ok ;FIXME ; Save caller
ex (sp),hl
push hl
ld hl,l00c2
ld (l00e2),hl ;ok ;FIXME ; Set standard as FIB
pop hl
ret
;
; Check file before read
; ENTRY Reg HL points to FIB
;
l14a9:
ex (sp),hl
ld (l00e4),hl ;ok ;FIXME ; Save caller for error
ex (sp),hl
ld (l00e2),hl ;ok ;FIXME ; Save FIB
bit in.bit,(hl) ; Test read allowed
ret nz ; Yeap
ld a,_NoRead
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Check file before write
; ENTRY Reg HL points to FIB
;
l14ba:
ex (sp),hl
ld (l00e4),hl ;ok ;FIXME ; Save caller for error
ex (sp),hl
ld (l00e2),hl ;ok ;FIXME ; Save FIB
bit out.bit,(hl) ; Test write allowed
ret nz ; Yeap
ld a,_NoWrite
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Function READLN(var)
; ENTRY Reg HL points to variable
;
l14cb:
db skip
;
; Function READ(var)
; ENTRY Reg HL points to variable
; EXIT Reg HL points to variable
;
l14cc:
xor a
ex (sp),hl ; Get caller
ld (l00e4),hl ;ok ;FIXME ; Save it
ex (sp),hl
push hl
ld hl,l00c2
ld (l00e2),hl ;ok ;FIXME ; Set standard device
res wr.bit,(hl) ; Reset write bit
push af ; Save mode
call l14e8 ; Read a line
pop af
or a ; Test READLN
jr z,l14e6
call l01e1 ; Give new line if so
l14e6:
pop hl
ret
;
; Read a line from keyboard
;
l14e8:
ld b,0 ; Reset flag
l14ea:
ld hl,l00d1 ; Point to buffer length
ld a,(hl) ; Get buffer length
cp _MaxBuf+1 ; Verify in range
jr c,l14f4
ld a,_MaxBuf ; Truncate if not
l14f4:
ld c,a
ld (hl),_MaxBuf ; Set default length
ld hl,(l00d2) ;ok ;FIXME ; Get top of memory
ld (l00d4),hl ;ok ;FIXME ; Unpack it
l14fd:
ld d,0 ; Reset character count
l14ff:
call readfromkbd ; Read character
ld (hl),a ; Unpack it
ld e,1 ; Init flag
cp bs ; Test backspace
jr z,l153f
;cp DEL ; Test delete
;jr z,l153f
dec e
cp CtrlX ; Test ^X
jr z,l153f
cp esc ; Test escape
jr z,l153f
cp eof ; Test end of file
jr z,l1550
cp cr ; Test end of line
jr z,l1556
cp ' ' ; Test printable
jr nc,l1533
cp CtrlC ; Test ^C
jr nz,l14ff
ld a,(l00dd) ;ok ;FIXME ; Get $C mode
or a ; Test abort
jr z,l14ff ; $C- - so ignore
ld ix,(l00e4) ;ok ;FIXME
jp l2016 ; Abort
;
; Found printable character
;
l1533:
ld a,c ; Get max
cp d ; Test against count
jr z,l14ff ; Yeap, ignore
ld a,(hl) ; Get character
inc d ; Advance counter
inc hl ; Point to next storage location
call puttoconsole_a ; Put to console
jr l14ff
;
; Special control detected: Backspace, DELete, ^X, ESCape
;
l153f:
dec d ; Fix count
jp m,l14fd ; Ignore if at 1st position
dec hl
call l0200 ; Position cursor left
db bs,' ',bs
db null
dec e ; Test backspace or delete
jr z,l14ff ; Yeap
jr l153f ; Else delete two characters on screen
;
; Found EOF
;
l1550:
inc b ; Test flag
dec b
jr z,l14ff ; Ignore input
jr l155a ; Close input line
;
; Found CR
;
l1556:
inc b ; Test flag
dec b
jr nz,l155e ; Ignore EOF
l155a:
ld (hl),eof ; Close line
jr l1566
l155e:
call l01e1 ; Give new line
ld (hl),cr ; Close line
inc hl
ld (hl),lf
l1566:
inc hl
ld (l00d6),hl ;ok ;FIXME ; Set top pointer
ret
;
; Get character from file or console buffer
;
l156b:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
jp nz,l15ed ; Force EOF if so
ld a,(hl)
bit wr.bit,a ; Test preread char
jp nz,l15e9 ; Fetch if so
and FIBtype ; Test device
jr nz,l15ab ; Yeap, standard I/O
inc hl ; Point to sector buffer
inc hl
ld a,(hl)
or a ; Test filled
jp p,l1597 ; Not yet
push hl
ex de,hl
ld c,_setdma
call l19ba ; set DTA
pop hl
ld c,_rdseq
push hl
call l19ba ; Read sector
pop hl
;jr z,l1595 ; Read was successfull
cp 128 ;EOF in NedoOS
jr nz,l1595 ; Read was successfull
;jr $ ;lister.pas
;CP/M has eofs in the end of last sector?
;do this by hand:
or a
jr z,read_load_noaddeofs ;full sector
;a=128+bytes loaded
neg
;a=128-bytes loaded
ld b,a
ld a,l
add a,127
ld e,a
adc a,h
sub e
ld d,a
;ld de,TmpBuff+127 ;de= Point to buffer end
ld a,eof;-1
ld (de),a
dec de
djnz $-2
read_load_noaddeofs
push hl
ld de,FIB.buff-2
add hl,de ; Point to buffer
ld (hl),eof ; Set EOF
pop hl
l1595:
xor a
ld (hl),a ; Reset buffer pointer
l1597:
inc (hl) ; Bump pointer
add a,FIB.buff-2
ld e,a
ld d,0
add hl,de ; Calculate current buffer
ld a,(hl)
cp eof ; Test EOF
jr nz,l15e0 ; Nope
ld hl,(l00e2) ;ok ;FIXME
inc hl
inc hl
dec (hl) ; Fix pointer if eof found
;push hl
; ld c,_close
; call BDOS_with_FCB1 ;с этим виснет lister в конце!!!
;pop hl
jr l15e0
l15ab:
dec a ; Test CON:
jr nz,l15c9
ld hl,(l00d4) ;ok ;FIXME ; Get current pointer
ld de,(l00d6) ;ok ;FIXME ; Get top pointer
or a
sbc hl,de ; Test more in buffer
jr c,l15bf ; Ok
ld b,-1
call l14ea ; Else get more
l15bf:
ld hl,(l00d4) ;ok ;FIXME ; Get current pointer
ld a,(hl)
inc hl ; Bump
ld (l00d4),hl ;ok ;FIXME
jr l15e0
l15c9:
dec a ; Test KBD:
jr nz,l15d2
call l00a3 ; Read KBD
ld a,l
jr l15e0
l15d2:
dec a ; Test AUX:
dec a
jr nz,l15dc
call l00af ; Get from auxiliary
ld a,l
jr l15e0
l15dc:
call l00b5 ; Read USR
ld a,l
l15e0:
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
set wr.bit,(hl) ; Set preread flag
inc hl
ld (hl),a ; Save character
dec hl
ret
l15e9:
inc hl ; Point to character buffer
ld a,(hl) ; Get character
dec hl
ret
l15ed:
ld a,eof ; Return EOF
ret
;
; Get character from current device
; Fix up controls
;
l15f0:
push hl
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld a,(hl)
and FIBtype ; Get device
cp RAMdevice ; Test RAM
jr z,l1622
l15fb:
call l156b ; Get character from device
cp ' '+1 ; Test control
jr nc,l160a ; Nope
cp eof ; Test EOF
jr z,l160a ; Yeap
res wr.bit,(hl) ; Reset preread
jr l15fb ; Then synchronize
l160a:
ld de,Number ; Set buffer
ld b,_MaxSamp ; Set max
l160f:
push bc
push de
call l156b ; Get character from device
pop de
pop bc
cp ' '+1 ; Test control
jr c,l1620 ; Yeap, end if so
res wr.bit,(hl) ; No preread
ld (de),a ; save character
inc de
djnz l160f
l1620:
xor a
ld (de),a ; Close buffer
l1622:
pop hl
ret
;
; Check negative sign of ASCII number
; ENTRY Location NUMBER filled
; EXIT Reg IX points to number buffer
; Reg B holds 0 on no negative sign
; and 1 on negative sign found
; Zero flag indicates empty buffer
;
l1624:
ld ix,Number ; Init pointer
ld a,(ix) ; Get character
or a
ret z ; Exit if zero
ld b,0
cp '-' ; Test negative sign
ret nz ; Nope
inc b ; Fix result
inc ix ; Skip pointer
ret
;
; Fix number conversion for error
; ENTRY Reg IX points behind number
; Carry set reflects overflow
; EXIT Carry set indicates error
; IORESULT set to error 010H
;
l1636:
jr c,l163d ; Fall into error
ld a,(ix) ; Test correct end
or a
ret z ; Yeap
l163d:
ld a,_IllNum
ld (l00d0),a ;ok ;FIXME ; Set error
scf
ret
;
; Get character from input READ(char)
; ENTRY Reg HL points to character variable
;
l1644:
push hl ; Save pointer
call l156b ; Get character
res wr.bit,(hl) ; Reset preread
pop hl ; Get back pointer
ld (hl),a ; Save character
ret
;
; Get byte from input READ(byte)
; ENTRY Reg HL points to byte variable
;
l164d:
db skip ; Set byte flag
;
; Get integer from input READ(integer)
; ENTRY Reg HL points to integer variable
;
l164e:
xor a ; Reset byte flag
ld c,a
push bc
call l15f0 ; Get number input
pop bc
call l1624 ; Test sign
ret z ; Empty number, exit
push bc
push hl
call cnv_int ; Convert ASCII to integer
pop de
pop bc
call l1636 ; Test error
ret c ; Yeap, exit
dec b ; Test negative sign
call z,l0783 ; Negate if so
ex de,hl
ld (hl),e ; Save low or byte
inc c
dec c ; Test byte
jr nz,l1670 ; Skip if so
inc hl
ld (hl),d ; Save high on integer
l1670:
ex de,hl
ret
;
; Get real from input READ(real)
; ENTRY Reg HL points to real variable
;
l1672:
call l15f0 ; Get ASCII number
call l1624 ; Test sign
ret z ; Empty number, exit
push bc
push hl
call cnv_flp ; Convert to real
exx
pop hl
pop bc
call l1636 ; Test error
ret c ; Yeap, exit
dec b ; Test negative sign
exx
call z,l0a8f ; Negate if so
exx
jp l05d1 ; Save real number
;
; Get string from input READ(string[max])
; ENTRY Reg HL points to string variable
; Reg B holds max characters in string
;
l168e:
push hl ; Save pointer
ex de,hl
ld c,0 ; Clear character count
l1692:
push bc
push de
call l156b ; Get character
pop de
pop bc
cp cr ; Test end of line
jr z,l16a8
cp eof ; Test end of file
jr z,l16a8
res wr.bit,(hl) ; Reset preread
inc c ; Advance count
inc de ; Advance pointer
ld (de),a
djnz l1692
l16a8:
pop hl ; Get back pointer
ld (hl),c ; Set length
ret
;
; Handle end of line after READLN from file
;
l16ab:
call l156b ; Get character
cp eof ; Test end of file
jr z,l16c5
res wr.bit,(hl) ; Reset preread
cp lf ; Test new line
jr z,l16c5
cp cr ; Wait for end of line
jr nz,l16ab
call l156b
cp lf ; Maybe new line
jr nz,l16c5
res wr.bit,(hl) ; Reset preread if so
l16c5:
ret
;
; Output character to device
; ENTRY Accu holds character
;
l16c6:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld c,a ; Save character
ld a,(l00d0) ;ok ;FIXME
or a ; Test I/O error
ret nz ; Exit if so
ld a,(hl) ; Get type
and FIBtype ; Test device
jr nz,l16e4 ; Yeap
inc hl ; Point to sector buffer
inc hl
push hl
ld a,(hl) ; Get pointer
add a,FIB.buff-2
ld e,a
ld d,0
add hl,de ; Make pointer absolute
ld (hl),c ; Save character
pop hl
inc (hl) ; Advance count
ret p ; Still in range
jr l170c ; Write record
l16e4:
cp RAMdevice ; Test store to RAM
jr z,l16fd ; Yeap
pop hl
ld b,0
push bc
push hl
dec a ; 1=CON:
jp z,l00a6 ; Put to console
dec a ; 3=LST:
dec a
jp z,l00a9 ; Put to printer
dec a ; 4=AUX:
jp z,l00ac ; Put to auxiliary
; 5=USR:
jp l00b2 ; Put to console
l16fd:
ld hl,(l00e8) ;ok ;FIXME ; Get string pointer
ld a,(l00ea) ;ok ;FIXME ; Get max length
cp (hl) ; Test in range
ret z ; Nope, exit
inc (hl) ; Bump count
ld e,(hl)
ld d,0
add hl,de ; Build address
ld (hl),c ; Store character
ret
;
; Write sector to file if any item in buffer
;
l170c:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
inc hl
inc hl
ld a,(hl) ; Get record pointer
or a ; Test any in buffer
ret z ; Nope, exit
ld (hl),0 ; Clear pointer
ld c,_wrseq
call l19ba ; Write record
ret z ; Ok, no errr
ld a,_WrErr
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Write character to device
; WRITE(char)
; ENTRY Reg L holds character
;
l1722:
ld a,l ; Get character
jp l16c6 ; Put it
;
; Write integer to device
; WRITE(int)
; WRITE(int:m)
; ENTRY Integer on stack
; Reg HL holds digit count (zero without count)
;
l1726:
pop bc
pop de
push bc
ld ix,(l00d2) ;ok ;FIXME ; Get top of memory for buffer
bit sgn.bit,h ; Test sign of count
jr z,l1737 ; >= 0
call l0783 ; Negate
ex de,hl ; Swap values
jr l1745
l1737:
ex de,hl
bit sgn.bit,h ; Test sign of number
jr z,l1745 ; >= 0
call l0783 ; Negate
ld (ix),'-' ; Init sign
inc ix
l1745:
push de
call l07c6 ; Convert integer to ASCII
l1749:
pop hl
call l04c8 ; Get byte from integer
ld de,(l00d2) ;ok ;FIXME ; Get back top of memory
push ix
pop hl
or a
sbc hl,de ; Calculate length of string
ld c,l
ex de,hl
l1759:
sub c ; Test against count
jr c,l176a ; Ignore if out of range
jr z,l176a
ld b,a ; Save count
push hl
l1760:
ld a,' '
push bc
call l16c6 ; Blank leading places
pop bc
djnz l1760
pop hl
l176a:
ld b,c ; Get back length
inc b
l176c:
dec b
ret z
ld a,(hl)
push bc
push hl
call l16c6 ; Type digits
pop hl
pop bc
inc hl
jr l176c
;
; Formatted write
; WRITE(real)
; WRITE(real:n)
; WRITE(real:n:m)
; ENTRY Reg HL holds fix comma places (-1 on none)
; Stack holds decimal places and real
; (Without decimal places defaults to 24)
;
l1779:
pop bc
pop de ; Get places
exx
pop hl ; Get number
pop de
pop bc
exx
push bc
ld ix,(l00d2) ;ok ;FIXME ; Get top of memory for buffer
push de
call l1027 ; Convert real to ASCII
jr l1749
;
; Boolean write
; WRITE(bool)
; WRITE(bool:m)
; ENTRY Reg HL holds places (0 on none)
; Stack holds boolean
;
l178b:
pop bc
pop de ; Get boolean
push bc
call l04c8 ; Get byte from integer
bit _LB,e ; Test bit
ld hl,l17a1
ld c,l17a1.l
jr nz,l1759 ; It is TRUE
ld hl,l17a5
ld c,l17a5.l
jr l1759 ; Tell FALSE
;
l17a1:
db 'TRUE'
l17a1.l equ $-l17a1
l17a5:
db 'FALSE'
l17a5.l equ $-l17a5
;
; String and formatted character write
; WRITE(string)
; WRITE(string:m)
; WRITE(char:m)
; ENTRY Reg HL holds places (0 on none)
; Stack holds string (chracter=string with length=1)
;
l17aa:
call l04c8 ; Get byte from integer for places
ld hl,2
add hl,sp ; Fix stack
ld c,(hl) ; Get length
inc hl
call l1759 ; Print right justified
pop de ; Get back caller
ld sp,hl ; Reset stack
push de
ret
;
; Immediate string write
; WRITE('string')
; ENTRY Stack holds string starting with length
;
l17ba:
pop hl ; Get pointer to string
ld a,(hl) ; Get length
inc hl
or a ; Test any
jr z,l17cc
ld b,a ; save length if so
l17c1:
ld a,(hl) ; Get character
push bc
push hl
call l16c6 ; Write it
pop hl
pop bc
inc hl
djnz l17c1
l17cc:
jp (hl)
;
; Give new line
; WRITELN{...}
;
l17cd:
ld a,cr
call l16c6 ; Give return
ld a,lf
jp l16c6 ; Followed by line feed
;
; The logical delimiter functions
; Function SEEKEOLN(device):boolean
; ENTRY Reg HL points to FIB
; EXIT Reg HL holds TRUE or FALSE
;
l17d7:
ld de,1*256+cr ; Set CR
jr l17e9
;
; Function EOLN(device):boolean
;
l17dc:
ld de,cr
jr l17e9
;
; Function SEEKEOF(device):boolean
;
l17e1:
ld de,1*256+eof ; Set EOF
jr l17e9
;
; Function EOF(device):boolean
;
l17e6: ;???
ld de,eof
l17e9:
ld (l00e2),hl ;ok ;FIXME ; Set device
bit in.bit,(hl) ; Test input possible
jr z,l180c ; Nope
l17f0:
push de
call l156b ; Get character
pop de
cp e ; Test end found
jr z,l1808 ; Yeap
cp eof ; Test end of file
jr z,l1808 ; Force TRUE if so
cp ' '+1 ; Test control
jr nc,l180c ; Nope
inc d ; Test control to be checked
dec d
jr z,l180c ; Yeap
res wr.bit,(hl) ; Reset preread
jr l17f0
l1808:
ld hl,_TRUE ; Return TRUE
ret
l180c:
ld hl,FALSE ; Return FALSE
ret
;
; Prepare typed files
; Procedure REWRITE(typed_file)
; ENTRY Reg HL points to FIB
; Reg DE holds length of record
;
l1810:
db skip
;
; Procedure RESET(typed_file)
;
l1811:
xor a
ld (l00e8),a ;ok ;FIXME ; Set mode (0=RESET)
ld (l00e6),de ;ok ;FIXME ; Save record length
call l187a ; Close file
ld a,(l00d0) ;ok ;FIXME ; Test error
or a
ret nz ; End if so
call l1430 ; Set up FIB ;opens/creates file!!!
ld a,(l00d0) ;ok ;FIXME ; Test error
or a
ret nz ; End if so
ld hl,(l00e2) ;ok ;FIXME ; Init FIB flag
ld (hl),_.in+_.out+_.read
inc hl
inc hl
ld (hl),a ; Init record pointer
ld de,FIB.cur-2
add hl,de ; Point to current record
ld (hl),a ; Clear it
inc hl
ld (hl),a
ld de,FIB.FCB+_rrn-FIB.cur-1
add hl,de ; Point to random record
ld (hl),a ; Clear it
inc hl
ld (hl),a
ld de,FIB.rec-FIB.FCB-_rrn-1
add hl,de ; Point to FIB record
ld a,(l00e8) ;ok ;FIXME
or a ; Test mode
jr nz,l1864 ; Skip RESET
;
; Perform RESET
;
push hl
ld bc,FixRecLen ; Set four bytes
xor a
call l1909 ; Prepare read
pop hl
inc hl
inc hl
ld c,(hl) ; Point to max records
inc hl
ld b,(hl)
ld hl,(l00e6) ;ok ;FIXME
or a
sbc hl,bc ; Test agianst tem in file
ret z ; Correct value
ld a,_InvRec
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Perform REWRITE
;
l1864:
push hl
xor a
ld (hl),a ; Clear record
inc hl
ld (hl),a
inc hl
ld de,(l00e6) ;ok ;FIXME ; Fetch length
ld (hl),e ; Store into FIB
inc hl
ld (hl),d
pop hl
ld bc,FixRecLen
ld a,Rec.New+Rec.Wr
jp l1909 ; Prepare write
;
; Procedure CLOSE(typed_file)
; ENTRY Reg HL points to FIB
;
l187a:
ld (l00e2),hl ;ok ;FIXME ; Save FIB
ld a,(hl) ; Get state
and _.in+_.out ; Test any action
ret z ; Nope
call l19ae ; Write record if requested
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld de,FIB.FCB+_rrn
add hl,de ; Point to random recird
xor a
ld (hl),a ; Clear it
inc hl
ld (hl),a
ld de,-FIB.FCB-_rrn+1
add hl,de ; Point to record
ld (hl),a ; Clear it
inc hl
inc hl
ld bc,FixRecLen
ld a,Rec.Wr
call l1909 ; Prepare write
call l19ae ; Write if requested
jp l1481 ; Close file
;
; Prepare write to record file
; ENTRY Reg HL points to FIB
;
l18a4:
ex (sp),hl
ld (l00e4),hl ;ok ;FIXME ; Save caller
ex (sp),hl
ld (l00e2),hl ;ok ;FIXME ; Save FIB
ld a,(hl)
and _.in+_.out ; Test I/O allowed
ret nz ; Yeap
l18b0:
ld a,_BlkErr
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Get structure from input READ(type)
; ENTRY Reg HL points to FIB
;
l18b6:
ld a,(l00d0) ;ok ;FIXME ; Get error
or a ; Test previous
ret nz ; Yeap
push hl
call l1a5a ; Get record data
ex de,hl
or a
sbc hl,de ; Test against last record
pop hl
jr nc,l18d6 ; Error
xor a
call l1909 ; Read
l18ca:
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
ld de,FIB.cur
add hl,de
inc (hl) ; Bump record
ret nz
inc hl
inc (hl)
ret
l18d6:
ld a,_IllEOF
ld (l00d0),a ; Set error
ret
;
; Put structure to output WRITE(type)
; ENTRY Reg HL points to FIB
;
l18dc:
ld a,(l00d0) ;ok ;FIXME ; Get error
or a ; Test previous
ret nz ; Yeap
push hl
call l1a5a ; Get record data
or a
sbc hl,de ; Test same size
ld a,Rec.Wr
jr nz,l18fc
ld hl,(l00e2) ;ok ;FIXME
ld de,FIB.rec
add hl,de ; Point to record
inc (hl) ; Bump it
jr nz,l18fa
inc hl
inc (hl)
jr z,l1902 ; Overflow error
l18fa:
ld a,Rec.New+Rec.Wr
l18fc:
pop hl
call l1909 ; Execute write
jr l18ca
l1902:
pop hl
ld a,_OvflErr
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Perform record IO
; ENTRY Reg HL points to FIB record field
; Reg BC holds record length
; (Four on CLOSE, RESET and REWRITE)
; Accu holds code :
; 0 : On RESET and READ
; 1 : On CLOSE and WRITE
; 3 : On WRITE and REWRITE
;
l1909:
ld (l00e9),a ;ok ;FIXME ; Save code
ex de,hl
l190d:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
bit rd.bit,(hl) ; Test known buffer
jr z,l1943 ; Nope
res rd.bit,(hl) ; Reset bit
ld a,(l00e9) ;ok ;FIXME ; Get mode
bit Rec.Wr.bit,a ; Test write
jr z,l1935 ; Nope, so read
inc hl
inc hl
ld a,(hl) ; Get record pointer
dec hl
dec hl
or a
jr nz,l1935 ; Not empty, so read
ld a,(l00e9) ;ok ;FIXME ; Get code
bit Rec.New.bit,a ; Test new
jr nz,l1943 ; Yeap
ld a,b ; Get counter
or a
jr nz,l1943
ld a,c ; Test new
or a
jp m,l1943
l1935:
push bc
push de
ld c,_rndrd
call l19ba ; Read record
pop de
pop bc
;jr nz,$
jr nz,l1991 ; Error return
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
l1943:
ld a,(l00e9) ;ok ;FIXME ; Get mode
bit Rec.Wr.bit,a ; Test write allowed
jr z,l194c ; Nope
set wr.bit,(hl) ; Set bit
l194c:
inc hl
inc hl
ld a,(hl) ; Get pointer to buffer
add a,FIB.buff-2
push de
ld e,a
ld d,0
add hl,de ; Get address of buffer
pop de
sub FIB.buff-2 ; Reset pointer
call l199a ; Swap pointer
l195c:
ldi ; move bytes
jp po,l1966 ; Test done
inc a ; Bump pointer
jp p,l195c ; Test done
dec a
l1966:
inc a
call l199a ; Swap back
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
inc hl
inc hl
and NOMSB ; Test remainder in buffer
ld (hl),a
jr nz,l198a ; Yeap
push bc
push de
push hl
call l19ae ; Write record
pop hl
pop de
pop bc
jr nz,l1994 ; Error return
push de
ld de,FIB.FCB+_rrn-2
add hl,de ; Point to record
pop de
inc (hl) ; Advance it
jr nz,l198a
inc hl
inc (hl)
l198a:
ld a,b ; Test all done
or c
jp nz,l190d ; Nope
ex de,hl
ret
l1991:
ld a,_IllEOF
db skip.2
l1994:
ld a,_WrErr
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Swap record pointers on request
; ENTRY Reg HL and DE hold pointer
; EXIT Register swapped on write selected
;
l199a:
push af
ld a,(l00e9) ;ok ;FIXME ; Get mode
bit Rec.Wr.bit,a ; Test selection
jr z,l19a3
ex de,hl ; Swap
l19a3:
pop af
ret
;
; Force record write
; Procedure FLUSH(type)
; ENTRY Reg HL holds FIB
;
l19a5:
ld (l00e2),hl ;ok ;FIXME ; Save FIB
call l19ae ; Write if possible
ret z
jr l1994 ; Set error
;
; Write random record if select, set read
;
l19ae:
ld c,_rndwr ; Set OS function
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
set rd.bit,(hl) ; Set read bit
bit wr.bit,(hl) ; Test write
ret z ; Nope
res wr.bit,(hl) ; Reset and write
;
; Execute file function
; ENTRY Reg C holds file function
; EXIT Zero flag reflects state of function
; Accu holds BDOS code
;
l19ba:
ld hl,(l00e2) ;ok ;FIXME ; Load FIB
push hl
push bc
ld de,FIB.buff
add hl,de ; Point to buffer
ex de,hl
ld c,_setdma
call BDOS ; Set disk buffer
pop bc
pop hl
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
call BDOS ; Execute OS function
or a ; Build result
ret
;
; Procedure SEEK(file,record)
; ENTRY Reg HL holds record seeked for
; FIB pushed onto stack
;
l19d5:
pop bc
pop de
ld (l00e2),de ;ok ;FIXME ; Save FIB
push bc
push hl
call l1a5a ; Get FIB data
pop de
or a
sbc hl,de ; Test record less size
jr c,l1a26 ; Error if so
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld bc,FIB.reclen ; Point to length of record
add hl,bc
ld c,(hl) ; Get record
inc hl
ld b,(hl)
inc hl
ld (hl),e ; Save record number
inc hl
ld (hl),d
call l1a2c ; Multiply it
ld bc,FixRecLen
add hl,bc ; Adjust for header
jr nc,l19fe
inc de
l19fe:
ld a,l
and NOMSB ; Get record pointer
add hl,hl ; * 2
ex de,hl
adc hl,hl
ex de,hl
ld d,e ; / 256
ld e,h
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
inc hl
inc hl
ld (hl),a ; Store record pointer
ld bc,FIB.FCB+_rrn-2
add hl,bc ; Point to random record
ld c,(hl) ; Get it
inc hl
ld b,(hl)
ex de,hl
or a
sbc hl,bc ; Test record already set
add hl,bc
ret z ; Yeap
push de
push hl
call l19ae ; Write record
pop de
pop hl
ld (hl),d ; Set current record
dec hl
ld (hl),e
ret
l1a26:
ld a,_SeekEOF
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Multiply record number by record length
; ENTRY Reg BC holds length of record
; Reg DE holds number of record
; EXIT Reg HL holds the product of both
;
l1a2c:
push de ; Copy number
exx
pop hl ; Get copy
exx
ld hl,0 ; Init result
ld d,h
ld e,l
ld a,16 ; Set bit length
l1a37:
add hl,hl ; Shift result
ex de,hl
adc hl,hl ; Treat as 32 bit number
ex de,hl
exx
add hl,hl ; Shift number
exx
jr nc,l1a45
add hl,bc ; Fix for carry
jr nc,l1a45
inc de
l1a45:
dec a
jr nz,l1a37 ; Loop on
ret
;
; Function EOF(device):boolean (untyped)
;
l1a49::
call l1a5d ; Get size of file
or a
sbc hl,de ; Test end
ld hl,FALSE
ret nz ; Return FALSE if not
inc hl ; Fix for TRUE
ret
;
; Get record position of file
; Function FILEPOS(file):integer
; ENTRY Reg HL holds FIB
; EXIT Reg HL holds current record
;
l1a55:
call l1a5d ; Get size of file
ex de,hl ; Into integer result
ret
;
; Get record data of file
; EXIT Reg HL holds size of file
; Reg DE holds current record
; Reg BC holds record length
;
l1a5a:
ld hl,(l00e2) ;ok ;FIXME ; Load FIB
;
; Get size of file
; Function FILESIZE(file):integer
; ENTRY Reg HL holds FIB
; EXIT Reg HL holds size of file in terms of records
; Reg DE holds current record
; Reg BC holds length of record
;
l1a5d:
ld de,FIB.rec
add hl,de ; Point to records
ld e,(hl) ; Get number of records
inc hl
ld d,(hl)
inc hl
push de
ld c,(hl) ; Get record length
inc hl
ld b,(hl)
inc hl
ld e,(hl) ; Get current record
inc hl
ld d,(hl)
pop hl
ret
;
; Prepare untyped files
; Procedure REWRITE(un_typed_file)
; ENTRY Reg HL points to FIB
;
l1a6f:
db skip
;
; Procedure RESET(un_typed_file)
;
l1a70:
;TODO полностью переписать!!!
xor a
ld (l00e8),a ;ok ;FIXME ; Save mode (0=RESET)
call l1ab0 ; Close open file
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
ret nz ; Exit if so
call l1430 ; Fix FIB
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
ret nz ; Exit if so
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld (hl),_.in+_.out ; Set flag
push hl
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
ld c,_filsiz
call BDOS ; Get size of file
pop hl
ld de,FIB.FCB+_rrn
add hl,de ; Point to size
xor a
ld c,(hl) ; Get size
ld (hl),a ; Reset size
inc hl
ld b,(hl)
ld (hl),a
ld de,FIB.rec-FIB.FCB-_rrn-1
add hl,de ; Point to record number
ld (hl),c ; Set it
inc hl
ld (hl),b
inc hl
ld (hl),RecLng ; Set standard record
inc hl
ld (hl),a
inc hl
ld (hl),a ; Init current record
inc hl
ld (hl),a
ret
;
; Close untyped file
; ENTRY Reg HL holds FIB
;
; Procedure CLOSE(un_typed_file)
;
l1ab0:
ld (l00e2),hl ;ok ;FIXME ; Save FIB
ld a,(hl) ; Get mode
and _.in+_.out ; Test access
ret z ; Nope
jp l1481 ; Close it
;
; Write block to untyped file
; Procedure BLOCKWRITE(file,buffer,count)
; ENTRY Reg HL holds number of records to be written
; On stack FIB and buffer
;
l1aba:
ld a,_rndwr ; Set function code
jr l1ac0
;
; Read block from untyped file
; Procedure BLOCKREAD(file,buffer,count)
; ENTRY Reg HL holds number of records to be read
; On stack FIB and buffer
;
l1abe:
ld a,_rndrd ; Set function code
l1ac0:
ld b,h ; Copy count
ld c,l
ld hl,l00f0 ; Point to scratch
ld (l00e6),hl ;ok ;FIXME ; Set for record
pop ix
pop de ; Get buffer
pop hl ; Get FIB
push ix
push bc
call l1afd ; Execute block I/O
pop bc
ld a,(l00d0) ;ok ;FIXME
or a ; Test error
ret nz ; Exit if so
ld hl,(l00f0) ;ok ;FIXME
sbc hl,bc ; Test all records processed
ret z ; Yeap
ld a,(l00e9) ;ok ;FIXME ; Get file function
cp _rndrd ; Test read
ld a,_IllEOF
jr z,l1ae9
ld a,_WrErr
l1ae9:
ld (l00d0),a ;ok ;FIXME ; Set error code accordingly
ret
;
; Write block to untyped file
; Procedure BLOCKWRITE(file,buffer,count,result)
; ENTRY Reg HL points to result
; On stack FIB, buffer and number of records
;
l1aed:
ld a,_rndwr ; Set function
jr l1af3
;
; Read block from untyped file
; Procedure BLOCKREAD(file,buffer,count,result)
; ENTRY Reg HL points to result
; On stack FIB, buffer and number of records
;
l1af1:
ld a,_rndrd ; Set function
l1af3:
ld (l00e6),hl ;ok ;FIXME ; Save result pointer
pop ix
pop bc ; Get count
pop de ; Get buffer
pop hl ; Get FIB
push ix
;
; Perform block IO
; ENTRY Accu holds file function
; Reg HL holds FIB
; Reg DE holds buffer
;
l1afd:
ld (l00e9),a ;ok ;FIXME ; Save function
ld (l00e2),hl ;ok ;FIXME ; Save FIB
ld a,(hl) ; Get mode
and _.in+_.out ; Test IO allowed
jp z,l18b0 ; Nope
ld hl,(l00e6) ;ok ;FIXME ; Get record address
xor a
ld (hl),a ; Clear record
inc hl
ld (hl),a
l1b10:
ld a,b
or c ; Test all done
jr z,l1b4d ; Yeap
push bc
push de
ld c,_setdma
call BDOS ; Set disk buffer
ld hl,(l00e2) ;ok ;FIXME ; Get back FIB
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
ld a,(l00e9) ;ok ;FIXME ; Get file function
ld c,a
call BDOS ; Execute I/O
pop de
pop bc
or a ; Test result
jr nz,l1b4d ; Not good
push de
ld hl,(l00e2) ;ok ;FIXME ; Get FIB again
ld de,FIB.FCB+_rrn
add hl,de ; Point to record
inc (hl) ; Advance record
jr nz,l1b3c
inc hl
inc (hl)
l1b3c:
pop de
ld hl,RecLng
add hl,de ; Advance buffer
ex de,hl
ld hl,(l00e6) ;ok ;FIXME
inc (hl) ; Advance record count
jr nz,l1b4a
inc hl
inc (hl)
l1b4a:
dec bc ; Count down requested length
jr l1b10
l1b4d:
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld de,FIB.FCB+_rrn
add hl,de ; Point to last record
ld c,(hl)
inc hl
ld b,(hl)
ld de,FIB.cur-FIB.FCB-_rrn-1
add hl,de ; Point to FIB record
ld (hl),c ; Save record number
inc hl
ld (hl),b
ld de,-FIB.rec
add hl,de ; Point to record
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
or a
sbc hl,bc ; Test against last record
ret nc
ex de,hl
ld (hl),c ; Save new max record
inc hl
ld (hl),b
ret
;
; Procedure SEEK(file,record)
; ENTRY Reg HL holds record seeked for
; FIB pushed onto stack
;
l1b6f:
pop bc
pop de
ld (l00e2),de ;ok ;FIXME ; Save FIB
push bc
push hl
call l1a5a ; Get record data
pop de
or a
sbc hl,de ; Test position
jp c,l1a26 ; Error if overflow
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld bc,FIB.cur
add hl,bc
ld (hl),e ; Save new position
inc hl
ld (hl),d
ld bc,FIB.FCB+_rrn-FIB.cur-1
add hl,bc
ld (hl),e ; Save in FCB, too
inc hl
ld (hl),d
ret
;
; Delete file
; Procedure ERASE(file)
; ENTRY Reg HL holds FIB
;
l1b93:
call l1c4c ; Check legal FIB
ret nz ; Nope
ld de,FIB.FCB
add hl,de ; Point to FCB
ex de,hl
ld c,_delete
call BDOS ; Delete file
inc a
ret nz
jr l1be4 ; Set error if unknown
;
; Rename file
; Procedure RENAME(file,newname)
; ENTRY FIB and name on stack
;
l1ba5:
pop iy
ld hl,(l00d2) ; Get top of memory for buffer
ld b,16 ; Set max
call l05e2 ; Assign string from stack
xor a
ld (de),a
pop hl ; Load FIB
push iy
call l1c4c ; Check legal FIB
ret nz ; Nope
push hl
call l03f2 ; Parse file
pop hl
push hl
ld de,FIB.FCB+DIRlen
add hl,de ; Point to 2nd FCB
ex de,hl
ld hl,l005c
ld bc,Fdrv+Fname+Fext
ldir ; move new name
pop hl
ld de,FIB.FCB
add hl,de ; Point to FCB
push hl
ex de,hl
ld c,_rename
call BDOS ; Rename
pop de
inc a ; Test success
jr z,l1be4 ; Nope
ld hl,l005c
ld bc,FCBlen
ldir ; Unpack new file
ret
l1be4:
ld a,_NoFile ; Set error
l1be6:
ld (l00d0),a ;ok ;FIXME
ret
;
; Perform executing new programs
; Procedure EXECUTE(File)
; ENTRY Reg HL points to FIB
;
l1bea:
db skip
;
; Procedure CHAIN(File)
;
l1beb:
xor a
ld (l00e8),a ;ok ;FIXME ; Set mode (0=CHAIN)
call l1c4c ; Test device ok
ret nz ; Nope
ld a,(l00d8) ;ok ;FIXME ; Test run mode
or a
ld a,_DirErr
jr z,l1be6 ; Must *NOT* be direct mode
ld hl,(l00e2) ;ok ;FIXME ; Get FIB
ld de,FIB.FCB
add hl,de ; Point to FCB
ld de,l005c
ld bc,FCBlen
ldir ; move to standard FCB
ld de,l005c
ld c,_open
call BDOS ; Open file ;WHERE IS CLOSE???
inc a
jr z,l1be4 ; File not found
ld hl,l1c33 ; Point to loader
ld de,l00b0
ld bc,l0019
ldir ; move loader to temporry location
ld de,0x0100;TPA ; Init loader address
ld a,(l00e8) ;ok ;FIXME ; Test mode
or a
jr nz,l1c2d
ld de,(progstartaddr);(TPA+1) ; Change address for CHAIN
l1c2d:
ld sp,0x0100;TPA ; Get local stack
jp l00b0 ; Go load
;
; ############### Start of loader ###############
;
; Loader will be moved into 00B0H temporary location
;
l1c33:
disp l00b0
_l1c33:
push de
ld c,_setdma
call BDOS ; Set disk buffer
ld de,l005c
ld c,_rdseq
call BDOS ; Read a code record
pop de
ld hl,RecLng
add hl,de ; Bump address
ex de,hl
;or a ; Test more
;jr z,_l1c33
cp 128 ;EOF in NedoOS
jr nz,_l1c33 ; Read was successfull
;jr $
jr 0x0100;TPA ; Start after loading
l0019 equ $-_l1c33
ent
;
; ################ End of loader ################
;
; Check legal device for file operation
; ENTRY Reg HL points to FIB
; EXIT Zero flag set if legal device
; If illegal, IOerror 20H will be set
;
l1c4c:
ld (l00e2),hl ;ok ;FIXME ; Save FIB
ld a,(hl) ; Get flag
and FIBtype ; Mask it
ret z ; 0000 menas file
ld a,_IllIO
ld (l00d0),a ;ok ;FIXME ; Set error
ret
;
; Load overlay file
; ENTRY Reg HL holds record procedure starts with
; Reg DE holds number of records to be read
;
; Overlay call follows:
; 2 Bytes hold last sector read
; 11 Bytes NAME.EXT of file
; n*128 Bytes record(s)
;
l1c59:
ld (l00e6),hl ;ok ;FIXME ; Save record
ld (l00e8),de ;ok ;FIXME ; Save record count
ex de,hl
pop hl
ld (l00e2),hl ;ok ;FIXME ; Save caller
ld c,(hl) ; Fetch last sector
ld (hl),e ; Set new one
inc hl
ld b,(hl)
ld (hl),d
ex de,hl ; Compare bew:old
or a
sbc hl,bc
jr z,l1cca ; Overlay already in memory
ex de,hl
inc hl
ld de,l005c
ld a,(l00dc) ;ok ;FIXME ; Get overlay drive
ld (de),a ; Store into standard FCB
inc de
ld bc,Fname+Fext
ldir ; move name to standard FCB
ld b,FCBlen-_ex
xor a
l1c82:
ld (de),a ; Clear remainder of FCB
inc de
djnz l1c82
push hl ; Save address of buffer
ld de,l005c
ld c,_open
call BDOS ; Open file
pop de ; Get back buffer address
inc a ; Test success
jr z,l1cd2 ; Nope
ld hl,(l00e6) ;ok ;FIXME ; Get start record
ld (l005c+_rrn),hl ;ok ;FIXME ; Set for random record
ld bc,(l00e8) ;ok ;FIXME ; Get record count
l1c9d:
push bc
push de
ld c,_setdma
call BDOS ; Set disk buffer
ld de,l005c
ld c,_rndrd
call BDOS ; Read from file
pop de
pop bc
or a ; Verify no error
jr nz,l1cd2 ; Error
ld hl,(l005c+_rrn) ;ok ;FIXME
inc hl ; Bump record
ld (l005c+_rrn),hl ;ok ;FIXME
ld hl,RecLng
add hl,de ; Get next address
ex de,hl
dec bc
ld a,b ; Test done
or c
jr nz,l1c9d ; Nope
ld de,l005c
ld c,_close
call BDOS ; Close file
l1cca:
ld hl,(l00e2) ; Get caller
ld de,2+Fname+Fext
add hl,de ; Skip header
jp (hl) ; Enter overlay
l1cd2:
ld ix,(l00e2) ; Get caller's PC
ld a,_OVLerr
jp l2029 ; Abort
;
; Procedure OVRDRIVE(drive)
; ENTRY Reg HL holds drive (1=A, 2=B, etc)
;
l1cdb:
call l04c8 ; Get byte from integer
cp 'P'-'@'+1 ; Test max
ret nc ; Exit on range error
ld (l00dc),a ;ok ;FIXME ; Set overlay drive
ret
;
; Procedure NEW(pointer)
; Procedure GETMEM(pointer,space)
; ENTRY Reg HL holds space required
; Variable pointer on stack
;
l1ce5:
ld (l00f0),hl ;ok ;FIXME ; Save space required
ex de,hl
pop hl
ex (sp),hl
ld (l00f2),hl ;ok ;FIXME ; Save address of variable
inc de
inc de
inc de
ld a,e
and -HeapLen ; Get modulo 4
ld e,a
ld hl,l00de
ld (l00f8),hl ;ok ;FIXME ; Init pointer
ld ix,(l00de) ;ok ;FIXME ; Get pointer to 1st free address
l1cff:
ld l,(ix+HeapLOlen)
ld h,(ix+HeapHIlen)
ld a,l ; Test assignment
or h
jr z,l1d51 ; Maybe free
sbc hl,de ; Test gap
jr nc,l1d1c
ld l,(ix+HeapLOadr); Get next address
ld h,(ix+HeapHIadr)
push hl
ld (l00f8),ix ;ok ;FIXME ; Save last address
pop ix ; Copy chain
jr l1cff
l1d1c:
jr nz,l1d28 ; Not same gap length
ld e,(ix+HeapLOadr); Get address if so
ld d,(ix+HeapHIadr)
push ix
jr l1d43 ; Save state
l1d28:
ld c,l ; Copy length
ld b,h
ld l,(ix+HeapLOadr); Get address
ld h,(ix+HeapHIadr)
l1d30:
push ix ; Save pointer
add ix,de ; Advance
ld (ix+HeapLOadr),l; Set start values
ld (ix+HeapHIadr),h
ld (ix+HeapLOlen),c
ld (ix+HeapHIlen),b
push ix
pop de ; Copy pointer
l1d43:
ld hl,(l00f8) ;ok ;FIXME ; Get pointer
ld (hl),e ; Set new link
inc hl
ld (hl),d
pop de
ld hl,(l00f2) ;ok ;FIXME
ld (hl),e ; Set into vriable
inc hl
ld (hl),d
ret
l1d51:
push ix
pop hl
add hl,de
ld (l00c4),hl ; Set new heap pointer
ld hl,(l00f0) ; Get space
ld bc,HeapLen
add hl,bc ; Get complete length
push ix
pop bc
add hl,bc
jp c,l1d75 ; Error if overlapping
ld bc,(l00c6) ; Get recursion pointer
sbc hl,bc ; Test against it
ld bc,0
ld hl,0
jp c,l1d30
;
; Heap error
;
l1d75:
ld a,_HeapErr
jp l2027 ; Set error
;
; Procedure DISPOSE(pointer)
; Procedure FREEMEM(pointer,space)
; ENTRY Reg HL holds space
; Variable pointer on stack
;
l1d7a:
ex de,hl ; Save space
pop hl
ex (sp),hl ; Get variable pointer
ld a,(hl) ; Get dynamic pointer
inc hl
ld h,(hl)
ld l,a
inc de ; Fix space
inc de
inc de
ld a,e
and -HeapLen ; Get modulo 4
ld e,a
ex de,hl
ld (l00f0),hl ; Save length
ld hl,(l00de) ; Load pointer to free heap
push hl
pop ix
or a
sbc hl,de ; Check pointer addresses
jr nc,l1de9
l1d97:
ld l,(ix+HeapLOadr); Get address
ld h,(ix+HeapHIadr)
push hl
or a
sbc hl,de ; Compare
jr nc,l1da7
pop ix
jr l1d97
l1da7:
pop hl
push de
pop iy
ld bc,(l00f0) ; Get length
ld (iy+HeapLOlen),c; Store it
ld (iy+HeapHIlen),b
ld (iy+HeapLOadr),l; Store address, too
ld (iy+HeapHIadr),h
ld (ix+HeapLOadr),e
ld (ix+HeapHIadr),d
push ix
pop hl
ld c,(ix+HeapLOlen); Get old length
ld b,(ix+HeapHIlen)
call l1e04 ; Compare
jr z,l1dd8 ; Match
ld e,(ix+HeapLOadr); Get address
ld d,(ix+HeapHIadr)
push de
pop ix
l1dd8:
push ix
pop hl
ld c,(ix+HeapLOlen)
ld b,(ix+HeapHIlen)
ld e,(ix+HeapLOadr)
ld d,(ix+HeapHIadr)
jr l1e04
l1de9:
ld hl,(l00de) ; Get pointer to free heap
ld (l00de),de ; Set new address
push de
pop ix
ld (ix+HeapLOadr),l; Set chain
ld (ix+HeapHIadr),h
ld bc,(l00f0) ; Get length
ld (ix+HeapLOlen),c
ld (ix+HeapHIlen),b
ex de,hl
l1e04:
add hl,bc ; Bump next
or a
sbc hl,de ; Test same
ret nz
push de
pop iy ; Copy pointer
ld hl,(l00c4) ; Get heap pointer
or a
sbc hl,de ; Test top found
jr z,l1e2f
ld a,(iy+HeapLOadr); Unpack address
ld (ix+HeapLOadr),a
ld a,(iy+HeapHIadr)
ld (ix+HeapHIadr),a
ld l,(iy+HeapLOlen)
ld h,(iy+HeapHIlen)
add hl,bc
ld (ix+HeapLOlen),l; Unpack new length
ld (ix+HeapHIlen),h
xor a
ret
l1e2f:
push ix
pop hl
ld (l00c4),hl ; Set new top heap pointer
ld b,HeapLen
l1e37:
ld (hl),0 ; Clear top
inc hl
djnz l1e37
ret
;
; Get free memory
; Function MEMAVAIL:integer
; EXIT Reg HL holds free memory in bytes
;
l1e3d:
call l1e4b ; Get memory
ld hl,(l00f4) ; Get available memory
ret
;
; Get max free memory
; Function MAXAVAIL:integer
; EXIT Reg HL holds free memory in bytes
;
l1e44:
call l1e4b ; Get memory
ld hl,(l00f6) ; Get max memory
ret
;
; Get free memory
;
l1e4b:
ld hl,0
ld (l00f4),hl ; Init available memory
ld (l00f6),hl
ld ix,(l00de) ; Get pointer to free heap
l1e58:
ld c,(ix+HeapLOlen)
ld b,(ix+HeapHIlen)
ld a,c
or b ; Test end of chain
jr z,l1e80
ld hl,(l00f4) ; Get old available memory
add hl,bc ; Add length
ld (l00f4),hl
ld hl,(l00f6) ; Get max
or a
sbc hl,bc ; Check it
jr nc,l1e75
ld (l00f6),bc ; Set new max
l1e75:
ld l,(ix+HeapLOadr); Get chain
ld h,(ix+HeapHIadr)
push hl
pop ix
jr l1e58 ; Loop
l1e80:
ld hl,(l00c6) ; Get recursion pointer
ld bc,-5
add hl,bc ; Build free address
ld de,(l00c4) ; Get heap pointer
or a
sbc hl,de ; Test any free
ret c
ex de,hl
ld hl,(l00f4) ; Get available memory
add hl,de ; Add gap
ld (l00f4),hl
ld hl,(l00f6) ; Get max
or a
sbc hl,de ; Subtract
ret nc
ld (l00f6),de ; Set new
ret
;
; Mark heap
; Procedure MARK(pointer)
; ENTRY Reg HL holds pointer
;
l1ea3:
ld de,(l00c4) ;ok ;FIXME ; Get heap pointer
ld (hl),e ; Store into variable
inc hl
ld (hl),d
ret
;
; Release heap
; Procedure RELEASE(pointer)
; ENTRY Reg HL holds pointer
;
l1eab:
ld e,(hl) ; Load heap from variable
inc hl
ld d,(hl)
ex de,hl
;
; Init heap
; ENTRY Reg HL points to 1st free location
;
l1eaf:
ld (l00c4),hl ;ok ;FIXME ; Set heap pointer
ld (l00de),hl ;ok ;FIXME
ld b,HeapLen
l1eb7:
ld (hl),0 ; Clear 4 bytes
inc hl
djnz l1eb7
ret
;
; Convert number to string
; Procedure STR(real,string)
; ENTRY Real pushed onto stack with formatting data
; Reg HL points to string
; Reg B holds length of string
;
l1ebd:
db skip
;
; Procedure STR(integer,string)
; ENTRY Integer pushed onto stack with digit count
; Reg HL points to string
; Reg B holds length of string
;
l1ebe:
xor a
ld c,a ; Save mode
ld (l00e8),hl ;ok ;FIXME ; Save string
xor a
ld (hl),a ; Init to empty string
ld (l00d0),a ;ok ;FIXME ; Clear error
ld a,b
ld (l00ea),a ;ok ;FIXME ; Save max length
ld hl,(l00e2) ;ok ;FIXME
ld (l00ed),hl ;ok ;FIXME ; Save current FIB
ld hl,l1f46
ld (l00e2),hl ;ok ;FIXME ; Set RAM device
pop hl ; Get caller
ld (l00e4),hl ;ok ;FIXME
pop hl ; Get digit count/comma places
inc c ; Test mode
dec c
jr nz,l1ee6
call l1726 ; Get integer string
jr l1ee9
l1ee6:
call l1779 ; Get real string
l1ee9:
ld hl,(l00ed) ;ok ;FIXME
ld (l00e2),hl ;ok ;FIXME ; Restore FIB
ld hl,(l00e4) ;ok ;FIXME ; Get caller
jp (hl)
;
; Convert string to number
; Procedure VAL(string,real,result)
; ENTRY String and address of real pushed onto stack
; Reg HL points to result
;
l1ef3:
db skip
;
; Procedure VAL(string,integer,result)
; ENTRY String and address of integer pushed onto stack
; Reg HL points to result
;
l1ef4:
xor a
ld (l00ec),a ;ok ;FIXME ; Save mode
ld (l00e8),hl ;ok ;FIXME ; Save result
ld hl,(l00e2) ;ok ;FIXME
ld (l00ed),hl ;ok ;FIXME ; Save current FIB
ld hl,l1f46
ld (l00e2),hl ;ok ;FIXME ; Set RAM FIB
pop hl
ld (l00e4),hl ;ok ;FIXME ; Save caller
pop hl
ld (l00ea),hl ;ok ;FIXME ; Save integer/real address
ld hl,l005c
ld b,1eh
call l05e2 ; Assign string from stack
xor a
ld (de),a
ld hl,(l00ea) ;ok ;FIXME ; Get back variable pointer
ld a,(l00ec) ;ok ;FIXME ; Test mode
or a
jr nz,l1f27
call l164e ; Convert to integer
jr l1f2a
l1f27:
call l1672 ; Convert to real
l1f2a:
ld hl,l00d0
ld a,(hl) ; Get IOResult
ld (hl),0 ; Clear
or a
ld h,a
ld l,a
jr z,l1f3d ; Test error
push ix
pop hl ; Get last address
ld de,l005c
sbc hl,de ; Get relative string error
l1f3d:
ex de,hl
ld hl,(l00e8) ; Point to result
ld (hl),e ; Save error or success
inc hl
ld (hl),d
jr l1ee9 ; Exit
;
; FIB for RAM storage
;
l1f46:
db _.in+_.out+RAMdevice
db 0
;
; Procedure RANDOMIZE
;
l1f48:
ld a,r ; Get refresh counter
ld (l00c8+3),a ; Set for random
ret
;
; Fill variable with constant value
; Procedure FILLCHAR(var,num,val)
; ENTRY Reg HL holds value
; Count and variable address pushed onto stack
;
l1f4e:
ex de,hl
pop ix
pop bc ; Get count
pop hl ; Get address
ld a,b
or c ; Test count zero
jr z,l1f62 ; Skip if so
ld (hl),e ; Store value
dec bc ; Fix count
ld a,b
or c ; Test count one
jr z,l1f62 ; Skip if so
ld d,h ; Copy address
ld e,l
inc de
l1f60:
ldir ; move value for fill
l1f62:
jp (ix)
;
; move variable to another
; Procedure MOVE(var1,var2,len)
; ENTRY Reg HL holds count
; Variables pushed onto stack
;
l1f64:
ld b,h ; Copy count
ld c,l
pop ix
pop de ; Get 2nd var
pop hl ; Get 1st one
ld a,b
or c
jr z,l1f62 ; Test zero length
sbc hl,de
add hl,de ; Test overlapping
jr nc,l1f60 ; move up if so
dec bc
add hl,bc ; Point to top
ex de,hl
add hl,bc
ex de,hl
inc bc
lddr ; move down
jp (ix)
;
; Get string from OS command line
; Function PARAMSTR(num):any_string
; ENTRY Reg HL holds number of substring
; EXIT Selected string on stack
;
l1f7d:
ld d,l ; Get number
inc d
dec d
jr z,l1f85 ; Skip if none
call l1f9d
l1f85:
pop ix ; Free stack
ld c,a ; Get length of string
ld b,0
cpl
ld l,a
ld h,-1
add hl,sp ; Build address on stack
ld sp,hl
ld (hl),c ; Store length
inc hl
ex de,hl
inc c ; Test any selected
dec c
jr z,l1f99 ; Nope
ldir ; Unpack it
l1f99:
jp (ix)
;
; Get number of parameters in OS command line
; Function PARAMCOUNT:integer;
;
l1f9b:
ld d,0 ; Set dummy selection
;
; Get parameters of OS command line
; ENTRY Reg D holds number of substring selected
; EXIT Reg DE points to selected substring
; Accu holds length of substring
; Reg HL holds index of substring
;
l1f9d:
ld hl,l0080 ; Init pointer
;ld a,MaxParams ; Test parameter count
;ld b,(hl)
;cp b
;jr nc,l1fa8
ld b,MaxParams ; Truncate to max
;l1fa8:
;inc hl
ld c,0 ; Init count
l1fab:
inc b
dec b ; Test end
jr z,l1fbc ; Yeap
ld a,(hl)
cp ' '
jr z,l1fb8 ; Skip white spaces
cp tab
jr nz,l1fbc
l1fb8:
inc hl
dec b
jr l1fab
l1fbc:
ld e,l ; Save pointer
l1fbd:
inc b
dec b ; Test done
jr z,l1fce ; Yeap
ld a,(hl)
cp ' '
jr z,l1fce ; Find white space
cp tab
jr z,l1fce
inc hl
dec b
jr l1fbd
l1fce:
ld a,l
sub e ; Test same position
jr z,l1fd6
inc c ; Count up index
dec d ; Test found
jr nz,l1fab
l1fd6:
ld l,c ; Get selected or last index
ld h,0 ; Make pointer relative
ld d,h
ret
;
; Procedure GOTOXY(x_val,y_val)
; ENTRY Reg HL holds y_val
; x_val on stack
;
l1fdb:
pop de
pop bc
push de
dec l ; Fix row
ld h,c
dec h ; Fix column
jp l02a2 ; Position cursor
;
; Function UPCASE(char):char
; ENTRY Reg HL holds character
; EXIT Reg HL holds UPPER case character
;
l1fe4:
ld a,l ; Get into accu
call doupcase ; Convert to upper case
ld l,a ; Bring it back
ret
;
; Execute BIOS function
; Procedures BIOS(func)
; BIOS(func,param)
; Functions BIOS(func):integer
; BIOS(func,param):integer
; BIOSHL(func,param):integer
; ENTRY Reg DE holds BIOS function
; Reg BC holds optional parameter
; EXIT Accu and reg HL hold result
;
l1fea:
ld hl,(OS+1) ; Get base address
add hl,de ; Make executable
add hl,de
add hl,de
jp (hl) ; Execute
;
; Get IO result
; Function IORESULT:integer
; EXIT Reg HL holds result
;
l1ff1:
ld hl,l00d0 ; Point to result
ld a,(hl) ; Get it
ld (hl),0 ; Clear after request
ld l,a
ld h,0
ret
;
; Control C entry - entered via RST after each statement
;
l1ffb:
call l0316 ; Test key pressed
ld a,h
or l
ret z ; Nope
ld a,(l00dd) ;ok ;FIXME ; Get $C mode
push af
xor a
ld (l00dd),a ;ok ;FIXME ; Set $C-
call l0320 ; Read from keyboard
pop af
ld (l00dd),a ;ok ;FIXME ; Reset $C mode
ld a,l
cp CtrlC ; Test Control-C
ret nz ; Nope
pop ix ; Fetch PC
l2016:
ld de,_CBRK ; Set CtrlC error
jr l202c ; Enter error routine
;
; Check IOResult after IO operation
; (May be turned off by {$I-})
;
l201b:
ld a,(l00d0) ;ok ;FIXME ; Test any error
or a
ret z ; Nope
pop ix ; Get caller
ld e,a ; Save code
ld d,_IO ; Set mode
jr l202c
l2027:
pop ix ; Get caller
l2029:
ld e,a ; Save code
ld d,_RT ; Set mode
;
; Common error handler
; ENTRY Reg D holds error mode
; Reg E holds error code
; Reg IX holds callers address
;
l202c:
;jr $
push de
call l037a ; Reset some things
pop de
xor a
ld (l00dd),a ; Set $C- mode
ld hl,(l00ce) ; Get current PC
ld a,h ; Check zero
or l
push ix
pop hl
ld bc,(l00cc) ; Get base PC
sbc hl,bc ; Subtract for base
ld bc,TPhead
add hl,bc ; Fix for 0100h start
ld (l00ce),hl ; Set current PC
or a ; Look for previous zero
jr nz,l2054 ; Nope
push de
push de
push hl
call l00d9 ; Do restart
pop de
l2054:
ld a,d
or a ; Test user break
jr nz,l206c
call l0200 ; Tell control C
db '^C'
db cr,lf
db 'User break'
db null
jr l2097
l206c:
dec a ; Test I/O error
jr nz,l207a
call l0200 ; Tell I/O error
db cr,lf
db 'I/O'
db null
jr l2088
l207a:
call l0200 ; Tell run time error
db cr,lf
db 'Run-time'
db null
l2088:
call l0200
db ' error '
db null
ld a,e
call l04b4 ; Print error byte
l2097:
call l0200 ; Tell current PC
db ', PC='
db null
ld hl,(l00ce) ; Get current PC
call l04af ; Print hex
jr l20bd ; Abort
;
; Process memory error
;
l20a8:
call l0200 ; Tell error
db 'Not enough memory'
db null
;
; Error detected, tell abort and break
;
l20bd:
call l0200 ; Tell it
db cr,lf
db 'Program aborted'
db cr,lf,null
;
; Halt program
;
l20d4:
ld a,(l00d8) ;ok ;FIXME ; Test run mode
or a
jp z,l278e ; Enter TP menue
if TERM == 0
YIELDGETKEYLOOP
endif
jp OS ; Exit .COM file
;
; Restart after error
;
l20de:
pop hl ; Get PC
pop de ; Clean stack
pop de
jp (hl) ; Restart
;
;end of runtime library
; %%%%%%%%%%%%%%%%%%%
; %%% MENUE ENTRY %%%
; %%%%%%%%%%%%%%%%%%%
;
; Enter here thru cold start
;
l20e2:
jp l215e ; Go to initializer
;
; Set up environment
;
l20e5:
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop) ; Get top of memory
pop bc
ld sp,hl
push bc
ld de,-StkSpc
add hl,de ; Allow some space
ld (l4548),hl ; Set top of memory
ld hl,l7ad7 ; Get top of used memory
ld bc,256*0+0 ; No break, no interrupt
call l0364 ; Init pointers
call l030a ; Give lead in sequence
call setlowvideo ; Set low video
jp setnormvideo ; Set normal video
;
; Init session and load work file if defined
;
l2104:
call l20e5 ; Set up environment
ld a,(l4542) ; Get compile flag
push af
ld a,(l4541) ; Test error message file read
or a
call nz,l2da4 ; Yeap, read it
call l2d8f ; Init session
call l2d4b ; Test work file defined
call nz,l2506 ; Yeap, load file
ld a,(l44f3) ; Get compiler mode
dec a
jr z,l2125 ; Compile to memory
pop af
ld (l4542),a ; Reset compile flag
l2125:
jp l223b ; Enter menue
;
; Give delimiter line
;
l2128:
call l0200
db '---------------------------------------'
db cr,lf,null
ret
;
; Give B blanks
;
l2156:
call l0200 ; Just do it
db ' ',null
djnz l2156
ret
;
; Come here after cold start
;
l215e:
;OS_HIDEFROMPARENT
;ld e,6 ;textmode
;OS_SETGFX
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop) ; Fetch top of memory
ld bc,-MEMGAP
add hl,bc
ld (l44f6),hl ; Set for available memory
;ld c,_retdsk
;call BDOS ; Get logged disk (return L=A=current drive)
xor a
inc a
ld (l44f8),a ; Save it
call l20e5 ; Set up environment
call l023e ; Clear screen
call l2128 ; Give delimiter
call l0200 ; Tell what we are
l217d:
db 'TURBO'
db ' Pascal system',null
call setlowvideo ; Set low video
ld b,7
call l2156 ; Give blanks
call l0200 ; Tell version
;
db 'Version 3.00A'
db cr,lf,null
ld b,27
call l2156 ; Give blanks
call l0200 ; Tell type and copyright
;
db 'CP/M-80, Z80'
db cr,lf,cr,lf
db 'Copyright (C) 1983,84,85 '
db null
call setnormvideo ; Set normal video
call l0200
;
db 'BORLAND Inc.'
db cr,lf,null
call l2128 ; Give delimiter
call l0200 ; Tell type of terminal
;
db lf
db 'Terminal: '
db null
ld hl,l0153
call l01d0 ; Give string
call l0200 ; Ask for error messages to be included
;
db cr,lf,lf,lf,lf
db 'Include error messages'
db null
call l2d21 ; Ask for YES or NO
ld (l4541),a ; Save result
call nz,l2da4 ; YES, read it
call l2d8f ; Init session
call l227a ; Display menue
;
; %%%%%%%%%%%%%%%%%%%&&&&&
; %%% TURBO WARM START %%%
; %%%%%%%%%%%%%%%%%%%&&&&&
;
l223b:
nop:ld sp,NEDOOSMEMTOP;ld sp,(TPAtop) ; Get top of stack
ld hl,l223b
push hl ; Set return address
call l01fa ; Indicate input requested
;
db cr+MSB,lf+MSB,'>'+MSB
db null
call readfromkbd ; Read character
call doupcase ; Convert to upper case
call l01e1 ; Give new line
ld hl,l2460
ld de,l2472
ld b,MainLen
call l2450 ; Find command
jr c,l227a ; Display menue if not found
jp (hl) ; Execute command
;
; Input option string
; On exit ^DE points to first non blank
;
l2261:
call l0200 ; Tell what we want
;
db ': '
db null
call l14e8 ; Get line
call l01e1 ; Give new line
ld de,l7ad7 ; Point to start of line
l2270:
ld a,(de) ; Get character
cp eof ; End on end of line
ret z
cp ' ' ; Skip blanks
ret nz
inc de
jr l2270
;
; Display menue
;
l227a:
call l023e ; Clear screen
call l01fa ; Give some info
;
db 'L'+MSB,'ogged drive:',' '+MSB
db null
;ld c,_retdsk
;call BDOS ; Fetch disk (return L=A=current drive)
xor a
add a,'A' ; Make ASCII
call puttoconsole_a ; Put to console
call l01fa ; Tell work file
;
db cr+MSB,lf+MSB,lf+MSB
db 'W'+MSB,'ork file:',' '+MSB
db null
call l3135 ; Type it
call l01fa ; Tell main file
;
db cr+MSB,lf+MSB
db 'M'+MSB,'ain file:',' '+MSB
db null
ld de,l44f9
call l2df8 ; Tell name of file
call l01fa ; Give selection
;
db cr+MSB,lf+MSB,lf+MSB
db 'E'+MSB,'dit '
db 'C'+MSB,'ompile '
db 'R'+MSB,'un '
db 'S'+MSB,'ave'
db cr,lf,lf
db 'e','X'+MSB,'ecute '
db 'D'+MSB,'ir '
db 'Q'+MSB,'uit compiler '
db 'O'+MSB,'ptions'
db cr,lf,lf
db 'Text: '
db null
ld de,(l4544) ; Get start of text
ld hl,(l4546) ; Get end of text
dec hl
call l2338 ; Tell free bytes
ld de,(l4546) ; Get end of text
ld hl,(l4548) ; Get top of available memory
;
; Tell free memory
; ENTRY Reg HL holds end address
; Reg DE holds start address
;
l232e:
call l0200 ; Tell free memory
;
db 'Free: '
db null
;
; Print decimal free bytes and hex addresses
; ENTRY Reg HL holds end address
; Reg DE holds start address
;
l2338:
push hl
push de
or a
sbc hl,de ; Calculate difference
call l2e5c ; Print it
call l0200 ; Tell bytes
;
db ' bytes ('
db null
pop hl ; Get start address
call l04af ; Print hex
ld a,'-'
call puttoconsole_a ; Give delimiter
pop hl ; Get end address
call l04af ; Print hex
ld a,')'
call puttoconsole_a ; Give closure
jp l01e1 ; Give new line
;
; Display arrow if compile selected
;
l2361:
dec a ; Test compile selected
jr nz,l2374 ; Nope, erase display
call l01fa
a2361:
db 'compile -> '
la2361 equ $-a2361
db null
ret
l2374:
ld b,la2361
jp l2156 ; Give blanks
;
; ##############################
; ### MAIN MENUE O - Options ###
; ##############################
;
l2379:
ld hl,l2379
push hl ; Set return address
call l023e ; Clear screen
ld a,(l44f3) ; Get compile mode
call l2361 ; Display arrow
call l01fa
db 'M'+MSB,'emory'
db cr,lf,null
call l2361 ; Display arrow
call l01fa
db 'C'+MSB,'om-file'
db cr,lf,null
call l2361 ; Display arrow
call l01fa
db 'c','H'+MSB,'n-file'
db cr,lf,lf,null
ld a,(l44f3) ; Get compile mode
cp 1 ; Test compile to memory
jr z,l2419 ; Yeap
call l01fa
db 'S'+MSB,'tart address:',' '+MSB
db null
ld hl,(l44f4) ; Get start address
call l04af ; Print hex
call l01fa
db ' (min '
db null
ld hl,l20e2 ; Get start address
call l04af ; Print hex
call l01fa
db ')'
db cr,lf
db 'E'+MSB,'nd address:',' '+MSB
db null
ld hl,(l44f6) ; Get top of available memory
call l04af ; Print hex
call l01fa
db ' (max '
db null
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop)
call l04af ; Print hex
call l01fa
db ')'
db cr,lf,lf,null
l2419:
call l01fa
db 'F'+MSB,'ind run-time error '
db 'Q'+MSB,'uit'
db cr,lf,lf
db '>'+MSB
db null
call readfromkbd ; Read character
call doupcase ; Convert to upper case
call l01e1 ; Give new line
ld hl,l246b
ld de,l2488
ld b,SubLen
call l2450 ; Find command
ret c ; Not found
jp (hl) ; Execute
;
; Find character in list ^HL of length in reg B
; Return address from table ^DE on success
; Set C if not found
;
l2450:
cp (hl) ; Compare
jr z,l245a ; Match
inc hl ; Skip character
inc de ; Skip address
inc de
djnz l2450 ; Go thru table
scf ; Indicate no match
ret
l245a:
ex de,hl
ld e,(hl) ; Fetch address
inc hl
ld d,(hl)
ex de,hl
ret
;
l2460:
db 'LWMECRSXDQO'
MainLen equ $-l2460
l246b:
db 'MCHSEFQ'
SubLen equ $-l246b
l2472:
dw l2cce ; L - Log drive
dw l24c9 ; W - Work file
dw l249a ; M - Main file
dw l2af8 ; E - Edit
dw l2827 ; C - Compile
dw l2a97 ; R - Run
dw l2639 ; S - Save
dw l2b2d ; X - eXecute
dw l2b93 ; D - Directory
dw l2b24 ; Q - Quit
dw l2379 ; O - Options
l2488:
dw l2740 ; M - Compile Memory
dw l2744 ; C - Compile Com-file
dw l2748 ; H - Compile cHn-file
dw l2750 ; S - Start address
dw l276e ; E - End address
dw l279b ; F - Find run-time error
dw l2496 ; Q - Quit
;
; ##########################
; ### SUB MENUE Q - Quit ###
; ##########################
;
l2496:
pop hl
jp l227a ; Display menue
;
; ################################
; ### MAIN MENUE M - Main file ###
; ################################
;
l249a:
call l0200
db cr,lf
db 'Main file name'
db null
call l2d9f ; Init a bit
call l2261 ; Input string
ld a,0
ld (l44f9+Fdrv),a ; Set default drive
ret z
call l2d2a ; Prepare .PAS file
ld de,l44f9 ; Point to main file
ld hl,l005c
ld bc,FCBlen
ldir ; Unpack FCB
ret
;
; ################################
; ### MAIN MENUE W - Work file ###
; ################################
;
l24c9:
ld hl,l25bc
ld (l259d+1),hl ; Redirect error
call l2601 ; Save work file
call l0200
db cr,lf
db 'Work file name'
db null
call l2261 ; Input string
ld a,0
ld (l451d+Fdrv),a ; Set no work file
jr nz,l24f6 ; Got input
call l2d8f ; Init session
jp l223b ; Enter menue
l24f6:
call l2d2a ; Prepare .PAS file
ld de,l451d
ld hl,l005c
ld bc,FCBlen
ldir ; Unpack work file
jr l250c ; Init and load text file
;
; Init a bit and load wirk file into memory
;
l2506:
ld hl,l25b7
ld (l259d+1),hl ; Redirect error
l250c:
ld hl,l25eb
ld (l257c+1),hl ; Set vector for file too big
call l2d8f ; Init session
ld de,l451d
;
; Load text file
; ENTRY Reg DE points to FCB
; EXIT Reg HL points to end of memory
;
l2518:
ld hl,(l4544) ; Get start of text
ld (l4460),hl ; Set block start pointer
ld (l4462),hl ; Set block end pointer
ld (l4450),hl ; Set current memory pointer
ld (l4454),hl ; Set block pointer
ld (l4458),hl ; Set edit pointer
ld (curstartofpage),hl ; Set start of screen
ld bc,(l4548) ; Get top of available memory
call l253b ; Load file
ld (hl),cr ; Close last line
inc hl
ld (l4546),hl ; Set end of text
push hl
ld c,_close
call BDOS_with_FCB1 ;WHY DOESN'T HELP???
pop hl
ret
;
; Load a file
; ENTRY Reg BC holds last available address
; Reg DE holds FCB
; Reg HL holds start address
; EXIT Reg HL holds end address
;
l253b: ;once
push hl
push bc
push de
call l0200 ; Tell action
db cr,lf
db 'Loading '
db null
call l2df8 ; Tell name of file
ld de,l005c
call l26dc ; Clear FCB
pop hl
ld bc,l0024
ldir
ld c,_open
call BDOS_with_FCB1 ; Open file
l2560:
;push af
;ld de,TmpBuff
;ld c,_setdma
;call _BDOS ; Set disk buffer
;pop af
pop bc
pop hl
inc a ; Test file found
jr z,l259d ; Nope
ld (l7b6d),bc ; Set last memory address
l2573:
ld bc,(l7b6d) ; Get last memory address
dec b
or a
sbc hl,bc ; Test room in memory
add hl,bc
l257c:
jp nc,a_DUMMY ; Nope
push hl
ld de,TmpBuff
ld c,_setdma
call _BDOS ; Set disk buffer
ld c,_rdseq
call BDOS_with_FCB1 ; Read record from file
pop hl
;or a ; Test end of file
;ret nz ; Yeap
cp 128
ret z ;EOF in NedoOS
if 1==1
;CP/M has eofs in the end of last sector?
;do this by hand:
or a
jr z,load_noaddeofs ;full sector
;a=128+bytes loaded
neg
;a=128-bytes loaded
ld b,a
ld de,TmpBuff+127 ; Point to buffer end
ld a,eof;-1
ld (de),a
dec de
djnz $-2
load_noaddeofs
endif
ld de,TmpBuff ; Point to buffer
ld b,RecLng
l258d:
;ld (hl),eof ;why there was not?
;inc hl
ld a,(de) ; Scan for EOF
cp -1
;jr z,$
ret z
and NOMSB ;why???
cp eof
;jr z,$
ret z
;dec hl
ld (hl),a ; Unpack data
inc hl
inc de
djnz l258d
jr l2573
l259d:
jp a_DUMMY ; *** REDIRECTED ***
;
; Tell file not found
;
l25a0:
call l0200
db cr,lf
db 'File not found'
db null
l25b4:
jp l2e76 ; Get ESCape
;
; Redirected error if work file read error
;
l25b7:
call l25a0 ; Tell file not found
jr l25ee
;
; Redirected error if work file not found
;
l25bc:
call l0200
db cr,lf
db 'New File'
db null
inc hl
push hl
ld hl,1000
call l021d ; Delay one second
pop hl
ret
;
; Tell file too big
;
l25d4:
ld hl,(l4546) ; Get end of text
call l0200
db cr,lf
db 'File too big'
db null
jr l25b4
;
; Process file too big error
;
l25eb:
call l25d4 ; Tell file too big
l25ee:
xor a
ld (l451d+Fdrv),a ; Indicate no file
jp l223b ; Enter menue
;
; Set extension .BAK
;
l25f5:
ld hl,l005c+Fdrv+Fname
ld (hl),'B'
inc hl
ld (hl),'A'
inc hl
ld (hl),'K'
ret
;
; Save work file on request
;
l2601:
db skip
;
; Save work file on request
;
l2602:
xor a
ex af,af'
ld a,(l447f) ; Test text changed
or a
ret z ; Nope
ex af,af'
or a ; Test request
jr z,l2639 ; Save file if not
call l0200
db 'Workfile '
db null
call l3135 ; Type name of file
call l0200
db ' not saved. Save'
db null
xor a
ld (l447f),a ; Set no text changed
call l2d21 ; Ask for YES or NO
ret z ; NO
;
; ###########################
; ### MAIN MENUE S - Save ###
; ###########################
;
l2639:
call l2d50 ; Get file
ld hl,l451d
push hl
ld de,l005c
ld bc,FCBlen
ldir ; Unpack file
call l0200 ; Tell action
db cr,lf
db 'Saving '
db null
ld de,l005c
call l2df8 ; Tell name of file
ld hl,(l4546) ; Get end of text
dec hl
ld (hl),eof ; Close text
call l25f5 ; Set extension .BAK
call l26d9 ; Clear FCB
ld c,_delete
call _BDOS ; Delete file
ld hl,l005c+Fdrv
ld de,l005c+DIRlen
xor a
ld (l447f),a ; Set no text changed
ld (de),a
inc a
ld (l44f2),a ; Set rename flag
inc de
ld bc,DIRlen-1
ldir ; Unpack name
pop hl
ld de,l005c
ld bc,DIRlen
ldir ; Get new file
ld c,_rename
call BDOS_with_FCB1 ; Rename it
ld hl,(l4544) ; Get start of text
l2692:
push hl
call l26d9 ; Clear FCB
ld c,_make
call _BDOS ; Create new file
pop hl
inc a
jr z,l26ed ; Error creating file
push hl
ld de,TmpBuff
push de
ld c,_setdma
call _BDOS ; Set disk buffer
pop de
pop hl
ld b,RecLng ; Set length of buffer
l26ad:
ld a,(hl) ; Get from memory
inc hl
l26af:
ld (de),a ; Put to buffer
inc de
djnz l26c6
ld b,a ; Save last character
push bc
push hl
ld c,_wrseq
call BDOS_with_FCB1 ; Write record to file
pop hl
pop bc
or a ; Test success
jr nz,l26fe ; Nope, write error
ld de,TmpBuff ; Reset pointer
ld a,b ; Get back last character
ld b,RecLng ; Reset buffer length
l26c6:
cp eof ; Test end of file
jr nz,l26ad ; Nope, go on
ld a,b
sub RecLng ; Test record boundary
ld a,eof
jr nz,l26af ; Nope, write end
ld c,_close ; Close file
;
; Do OS call with standard FCB
;
BDOS_with_FCB1:
ld de,l005c
jp _BDOS ; Do file call
;
; Clear FCB
;
l26d9:
ld de,l005c
;
; Clear FCB ^DE
;
l26dc:
push de
ld hl,_ex
add hl,de ; Point to extent
ld (hl),0 ; Clear it
ld d,h
ld e,l
inc de
ld bc,FCBlen-_ex-1
ldir ; Clear remainder
pop de
ret
;
; Create file error
;
l26ed:
call l0200 ; Tell error
db ' Directory'
db null
jr l2708
;
; Write file error
;
l26fe:
call l0200 ; Tell error
db ' Disk'
db null
l2708:
call l0200
db ' full'
db null
call l2e76 ; Get ESCape
call l26d9 ; Clear FCB
ld c,_delete
call BDOS_with_FCB1 ; Delete file
ld a,(l44f2) ; Test to be renamed
or a
ret z ; Nope
ld (l447f),a ; Set text changed
ld hl,l005c+Fdrv
ld de,l005c+DIRlen
xor a
ld (l44f2),a ; Clear rename flag
ld (de),a ; Clear name entry
inc de
ld bc,DIRlen-1
ldir ; Unpack FCB
call l25f5 ; Set extension .BAK
ld c,_rename
call BDOS_with_FCB1 ; Rename file
jp l223b ; Enter menue
;
; ####################################
; ### SUB MENUE M - Compile Memory ###
; ####################################
;
l2740:
ld a,1 ; Set memory
jr l274a
;
; ######################################
; ### SUB MENUE C - Compile Com-file ###
; ######################################
;
l2744:
ld a,2 ; Set .COM file
jr l274a
;
; ######################################
; ### SUB MENUE H - Compile cHn-file ###
; ######################################
;
l2748:
ld a,3 ; Set .CHN file
l274a:
ld (l44f3),a ; Set compile mode
jp l2d9f ; Force compile
;
; ###################################
; ### SUB MENUE S - Start address ###
; ###################################
;
l2750:
call l0200 ; Tell what we want
db 'Start address'
db null
call l2261 ; Input string
ld hl,l20e2 ; Set default
call nz,l2dd9 ; Get new hex value
ld (l44f4),hl ; Save new start address
ret
;
; #################################
; ### SUB MENUE E - End address ###
; #################################
;
l276e:
call l0200 ; Tell what we want
db 'End address'
db null
call l2261 ; Input string
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop)
ld bc,-MEMGAP
add hl,bc ; Calculate default
call nz,l2dd9 ; Get new hex value
ld (l44f6),hl ; Set top of available memory
ret
;
; Exit memory resident program
;
l278e:
call l20e5 ; Set up environment
ld hl,(l00ce) ; Get current PC
ld a,h
or l
jr nz,l27b1 ; Process error
jp l223b ; Enter menue
;
; #########################################
; ### SUB MENUE F - Find run-time error ###
; #########################################
;
l279b:
call l0200 ; Tell what we want
db 'Enter PC'
db null
call l2261 ; Input string
ret z ; Empty
call l2dd9 ; Get hex PC
ld (l00ce),hl ; Set current PC
l27b1:
call l01e1 ; Give new line
call l27d7 ; Load file into memory
ld hl,0
ld (l7904),hl ; Clear address
ld a,2
ld (CmpTyp),a ; Set searching
call l0200 ; Tell searching
db cr,lf
db 'Searching'
db null
call l2d9f ; Force compile
jp l28d0 ; Go compile
;
; Load file into memory
;
l27d7:
call l2d4b ; Test work file defined
call z,l2d50 ; Get file if not
call l2d7a ; Test main file here
l27e0:
ld hl,l451d
jr nz,l27ea ; Got any file
call l2d50 ; Get file
jr l2808
l27ea:
call l2d7f ; Test same files
jr z,l27e0 ; Yeap, get another one
call l2602 ; Save work file
ld hl,l25eb
ld (l257c+1),hl ; Set vector for file too big
ld hl,l25b7
ld (l259d+1),hl ; Set vector for read error
ld de,l44f9 ; Point to main file
push de
call l2518 ; Load text file ;closes automatically
ld a,1
pop hl
l2808:
ld (l44f1),a ; Re/Set file flag
ld de,FFCB
ld bc,FCBlen
ldir ; Unpack file
xor a
ld (CmpTyp),a ; Set compile to memory
ld hl,NEDOOSMEMTOP;ld hl,(TPAtop)
ld (l790a),hl ; Set end of code
l281d:
ld hl,(l4546) ; Get end of text
ld (hl),eof ; Set end of file
inc hl
ld (l7904),hl ; Set for code start address
ret
;
; ##############################
; ### MAIN MENUE C - Compile ###
; ##############################
;
l2827:
call l27d7 ; Load file into memory
ld a,(l44f3) ; Get compile mode
dec a ; Test compile to memory
jp z,l28aa ; Yeap
dec a ; Test compile to .COM file
push af
jr nz,l283c ; Nope
ld a,'C' ; Load .COM
ld hl,'O'+'M'*256
jr l2841
l283c:
ld a,'C' ; Load .CHN
ld hl,'H'+'N'*256
l2841:
ld (FFCB+Fdrv+Fname),a
ld (FFCB+Fdrv+Fname+1),hl
ld a,1
ld (CmpTyp),a ; Set compile to file
ld hl,(l44f4) ; Get start address of compiler
ld (l7904),hl ; Save
ld hl,(l44f6) ; Get top of available memory
ld (l790a),hl ; Save also
ld de,FFCB
push de
call l26dc ; Clear FCB
ld c,_delete
call _BDOS ; Delete file
pop de
ld c,_make
call _BDOS ; Create new file
inc a ; Test success
jp z,l2a5a ; Nope, error
pop af ; Get back .COM or .CHN
ld hl,0x0100;TPA
jr z,l2877 ; Got .COM
ld hl,(l7904) ; Get code start address
l2877:
ld (CodePC),hl ; Save for current PC
ex de,hl
l287b:
ld hl,(l7904) ; Get code start address
scf
sbc hl,de ; Test end reached
jr c,l28a9 ; Yeap
ld hl,(l7904) ; Get code start address
ld (progstartaddr),hl;(TPA+1),hl ; Set as start address
push de
ld c,_setdma
call _BDOS ; Set disk buffer
ld c,_wrseq
ld de,FFCB
call _BDOS ; Write record to file
pop de
ld hl,l20e2
ld (progstartaddr),hl;(TPA+1),hl ; Reset start address
;or a ; Test I/O success
;jp nz,l2a5a ; Error, disk full
ld hl,RecLng
add hl,de ; Advance buffer
ex de,hl
jr l287b
l28a9:
db skip
l28aa:
xor a
call l0200 ; Tell compiling
;
db cr,lf
db 'Compiling '
db null
ld de,FFCB
or a ; Test compile to memory
jr z,l28cd ; Yeap
call l0200 ; Indicate file
;
db ' --> '
db null
call l2df8 ; Tell name of file
l28cd:
call l2d9f ; Force compile
l28d0:
call l01e1 ; Give new line
call COMPILE ; Compile ;must close output file!!!
ld a,(l7901) ; Get error code
cp _ABORT ; Test abort
jr nz,l28fa ; Nope
call l0200 ; Tell abortion
;
db cr,lf,lf
db 'Compilation aborted'
db null
jp l223b ; Enter menue
l28fa:
call l0200 ; Tell lines
db ' lines'
db cr,lf,lf,null
ld a,(l7901) ; Get error code
or a ; Test any error
jp nz,l2970 ; Yeap
ld a,(CmpTyp) ; Get compile flag
cp 2 ; Test searching
jr nz,l292a ; Nope
call l2a7a ; Tell error position
call l0200
db 'not found'
db cr,lf,null
jp l223b ; Re-enter menue
l292a:
or a ; Test compile to memory
jr z,l293a ; Yeap
ld hl,(l7904) ; Get code start address
ld de,l20e2 ; Get start of application
or a
sbc hl,de
add hl,de
call nz,l232e ; Tell free
l293a:
call l0200
db 'Code: '
db null
ld de,(l7904) ; Get code start address
ld hl,(l7906) ; Get code end address
push hl
dec hl
call l2338 ; Tell free bytes
pop de
ld hl,(DataBeg) ; Get start of data
push hl
call l232e ; Tell free
pop de
inc de
ld hl,(l790a) ; Get end of code
call l0200
db 'Data: '
db null
call l2338 ; Tell free bytes
ld a,-1
ld (l4542),a ; Set no compile
ret
;
; Process compiler error
;
l2970:
cp _DskFull ; Test disk error
jp nc,l2a5a ; Error, disk full
cp _FndRTerr ; Test run-time error found
jr nc,l29ec ; Yeap
ld b,a ; Save error number
call l0200 ; Tell error
db 'Error '
db null
ld h,0
ld l,b ; Build 16 bit number
push bc
call l2e61 ; Print it
pop bc
ld a,(l4541) ; Test error message file read
or a
jr z,l29f8 ; No message file
ld hl,(l429e) ; Get base of message file
l2995:
ld a,(hl) ; Get character
cp eof ; Test end of message
jr z,l29f8 ; Yeap
cp ' ' ; Test control
jr c,l29ad ; Yeap, skip it
sub '0' ; Build number - always two digits
ld c,a
add a,a
add a,a
add a,c
add a,a
inc hl
add a,(hl) ; Combine number
sub '0' ; Fix it
inc hl
cp b ; Test message found
jr z,l29b6 ; Got it
l29ad:
ld a,(hl)
inc hl
cp cr ; Skip to end of line
jr nz,l29ad
inc hl
jr l2995 ; Try next line
l29b6:
call l0200 ; Tell result
;
db ': '
db null
l29bc:
ld a,(hl) ; Get character
cp cr ; Test end of text
jr z,l29f8 ; That's all
cp ' ' ; Test combined message
jr nc,l29e6 ; Nope
ld de,(l429e) ; Get base of message file
l29c9:
ld a,(de) ; Get character
inc de
cp ' ' ; Test printable
jr nc,l29dd ; Yeap, skip it
cp (hl) ; Test extension found
jr nz,l29dd ; Nope
l29d2:
ld a,(de) ; Get from extended part
cp cr ; Test end of line
jr z,l29e9 ; Yeap
call puttoconsole_a ; Put substring to console
inc de
jr l29d2
l29dd:
ld a,(de)
inc de
cp cr ; Skip this line
jr nz,l29dd
inc de
jr l29c9
l29e6:
call puttoconsole_a ; Put to console
l29e9:
inc hl
jr l29bc ; Loop on
;
; Got position of run-time error
;
l29ec:
call l2a7a ; Tell error position
call l0200
db 'found'
db null
l29f8:
xor a
ld (l44f1),a ; Clear file flag
ld a,(IncFlg) ; Test read from memory
or a
jr z,l2a41 ; Nope
ld a,'.'
call puttoconsole_a ; Put to console
call l2602 ; Save work file
ld de,l451d
ld hl,l790f
ld bc,Fdrv+Fname+Fext
ldir ; Copy include file
call l2506 ; Load it
call l0200
db cr,lf
db 'Error found in above include file'
db null
jr l2a51
l2a41:
call l2d7a ; Test main file here
jr z,l2a51 ; Nope
ld de,l451d
ld hl,l44f9 ; Point to main file
ld bc,Fdrv+Fname+Fext
ldir ; Copy file
l2a51:
call l2e76 ; Get ESCape
ld hl,(l790c) ; Fetch current editor address
jp l2afe ; And fall into edit
;
; Process disk full
;
l2a5a:
call l0200 ; Tell error
;
db 'Disk or directory full'
db null
call l2e76 ; Get ESCape
jp l223b ; Enter menue
;
; Tell error position message
;
l2a7a:
call l0200
db 'Run-time error position '
db null
ret
;
; ##########################
; ### MAIN MENUE R - Run ###
; ##########################
;
l2a97:
ld a,(l4542) ; Get compile flag
or a
call z,l2827 ; Compile before run
ld a,(l44f3) ; Get compile flag
dec a
jr z,l2adf ; Got to memory
dec a
ret nz ; Skip chain
call l2b33 ; Load overlay file
ret z ; Not found
call l2d7a ; Test main file here
ld hl,l451d
jr z,l2ab5 ; Nope
ld hl,l44f9 ; Point to main file
l2ab5:
ld de,FFCB
ld bc,Fdrv+Fname+Fext
ldir ; Unpack FCB
ld a,'C' ; Set .COM
ld hl,'O'+'M'*256
ld (FFCB+Fdrv+Fname),a
ld (FFCB+Fdrv+Fname+1),hl
ld de,FFCB
call l26dc ; Clear FCB
push de
ld c,_open
call _BDOS ; Open file ;WHERE IS CLOSE???
pop hl
inc a ; Test file here
jp z,l2104 ; Nope, init session
ld de,l42a0 ; Set dummy parameter
jp l2b7a ; Prepare overlay
l2adf:
ld (l0080),a ; Clear parameter
call l281d ; Set text and code pointer
call l0200 ; Tell running
db cr,lf
db 'Running'
db cr,lf,null
ld hl,(l7904) ; Get code start address
jp (hl) ; And go
;
; ###########################
; ### MAIN MENUE E - Edit ###
; ###########################
;
l2af8:
call l2d50 ; Get file
ld hl,-1 ; Set zero offset
l2afe:
push hl
ld hl,(l00a6+1) ;ok ;FIXME
ld (l421e),hl ; Change I/O
ld hl,l4214
ld (l00a6+1),hl ;ok ;FIXME
pop hl
jp l2e91 ; Go edit
;
; Control: EXIT EDITOR
;
l2b0f:
call l3e40 ; Sample character
ld hl,(l0169) ; Get screen lines
dec l ; Fix row
ld h,0 ; Set column
call l02a2 ; Position cursor
ld hl,(l421e)
ld (l00a6+1),hl ; Reset I/O
jp l223b
;
; ###########################
; ### MAIN MENUE Q - Quit ###
; ###########################
;
l2b24:
call l2601 ; Save work file
call l0310 ; Give lead out sequence
jp OS ; Exit to OS
;
; ##############################
; ### MAIN MENUE X - eXecute ###
; ##############################
;
l2b2d:
call l2b33 ; Load overlay file
ret z ; Not found
jr l2b5a ; Go
;
; Load overlay file
; Z set says not found
;
l2b33:
call l2601 ; Save work file
ld de,l217d ; Set name
ld a,'O'
ld hl,'V'+'R'*256
call l2e20 ; Prepare .OVR file
ret z
ld de,a_OVLADR-RecLng
l2b45:
ld hl,RecLng
add hl,de ; Build disk buffer address
push hl
ex de,hl
ld c,_setdma
call BDOS ; Set disk buffer
ld c,_rdseq
call BDOS_with_FCB1 ; Read record
pop de
;or a ; Test end of file
;jr z,l2b45 ; Nope, loop on
cp 128 ;EOF in NedoOS
jr nz,l2b45 ; Read was successfull
ret
;
; Execute file
;
l2b5a:
call l0200 ; Tell program
db cr,lf
db 'Program'
db null
call l2261 ; Input string
jp z,l2104 ; No input
ld a,'C'
ld hl,'O'+'M'*256
call l2e20 ; Prepare .COM file
jr z,l2b5a ; Not there, retry
ld hl,l005c
l2b7a:
push de ; Set argument pointer
push hl ; Set FCB
ld a,(l44f8)
push af ; Set logged disk
ld hl,l03ee
push hl ; Set parse file routine
ld hl,l00f4
push hl ; Set available memory
ld hl,l4450
push hl ; Set current memory pointer
ld hl,l2104
push hl ; Set return address
jp a_OVLADR ; Execute overlay
;
; ################################
; ### MAIN MENUE D - Directory ###
; ################################
fcbmask
db 0
db "???????????"
ds FCB_sz-11-1
fcbmask_filename=fcbmask+FCB_FNAME
;
l2b93:
call l0200
db 'Dir mask'
db null
call l2261 ; Input string
call l03ee ; Parse file
;ld c,_retdsk
;call _BDOS ; Return current disk (return L=A=current drive)
xor a
push af
push af
ld a,(l005c) ;ok ;FIXME ; Get disk
or a ; Test default
jr z,l2bbb ; Yeap
pop hl ; Clean stack
dec a
ld e,a
push af ; Set new disk
;ld c,_seldsk
;call _BDOS ; Select disk
l2bbb:
pop af
;add a,'A' ; Make disk ASCII
;ld (l2c8d),a ; Save disk
;ld de,TmpBuff
;ld c,_setdma
;call _BDOS ; Set disk buffer
ld de,0 ; Clear flag and count
ld c,_srcfrs
l2bce:
push de
push bc
ld de,TmpBuff
ld c,_setdma
call _BDOS ; Set disk buffer
pop bc
ld de,fcbmask
call BDOS_with_FCB1 ; Search for file
pop de
ld c,a
inc a ; Test valid one
jr z,l2c29 ; Nope
ld a,c
add a,a ; Result *32
add a,a
add a,a
add a,a
add a,a
ld c,a
ld b,0
ld hl,TmpBuff+_SYS
add hl,bc ; Point to SYS bit
bit 7,(hl) ; Test set
jr nz,l2c25 ; Yeap, skip display
ld d,-1 ; Set any found flag
ld hl,TmpBuff
add hl,bc ; Point to entry
inc e ; Test first file
dec e
jr nz,l2bff ; Nope
ld a,(l0168) ; Get screen columns
dec a
ld e,-1
l2bf8:
inc e
sub Dirlng ; Calculate files per line
jr nc,l2bf8
jr l2c05
l2bff:
call l0200
;
db ': '
db null
l2c05:
ld b,Fname+Fext ; Set length
l2c07:
inc hl
ld a,(hl)
and NOMSB ; Strip off offset
call puttoconsole_a ; Put to console
ld a,b
cp Fext+1 ; Test extension
ld a,' '
call z,puttoconsole_a ; Put blank to console if so
djnz l2c07
dec e ; Test remainder in line
jr z,l2c22 ; Nope
ld a,' '
call puttoconsole_a ; Put to console
jr l2c25
l2c22:
call l01e1 ; Give new line
l2c25:
ld c,_srcnxt ; Search next
jr l2bce
l2c29:
inc e ; Test any file left
dec e
call nz,l01e1 ; Give new line if so
inc d ; Test any file found
jr z,l2c3e ; Yeap
call l0200 ; Else tell it
;
db 'No file'
db cr,lf,null
l2c3e:
call l01e1 ; Give new line
if 0
;
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; !!! FOLLOWING IS ERRONEOUS ON CP/M 3.x !!!
; !!! USES BDOS FUNCTION 46 ON CP/M 3.x !!!
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
ld c,_getdpb
call BDOS ; Fetch disk parameter block
push hl
pop ix ; Copy it
ld a,(ix+3) ; Get block mask
inc a ; Fix
rra ; DIV 8 (1-> 1k, 2->2k etc.)
rra
rra
and DPBMASK ; Mask it
ld (l7b71),a ; Save block size
ld l,(ix+5) ; Fetch block count
ld h,(ix+6)
ld (l7b6f),hl ; Save it
inc hl ; Fix
call l2cc6 ; Build size in bytes
push hl ; Save it
;
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; !!! THE ALLOCATION VECTOR MAY BE FOUND IN ANOTHER !!!
; !!! MEMORY BANK RUNNING CP/M 3.X. !!!
; !!! THE NEXT CALCULATION MAY BE WRONG THEREFORE !!!
; !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;
ld c,_getalv
call BDOS ; Get allocation vector
ex de,hl
ld hl,(l7b6f) ; Get block count
ld bc,0
call l2ca5 ; Get free blocks
ld h,b
ld l,c
call l2cc6 ; Build size in bytes
call l0200 ; Tell size
;
db 'Bytes Remaining On '
l2c8d:
db 'X: '
db null
ex de,hl
pop hl ; Get back total size
or a
sbc hl,de ; Calculate free bytes
call l2e61 ; Print number
ld a,'k'
call puttoconsole_a ; Put to console
endif
pop af ; Get back selected disk
ld e,a
ret
;ld c,_seldsk
;jp _BDOS ; Select disk
;
; BC holds resulting block count
; DE holds allocation vector
; HL holds block count
;
; BC holds free blocks
;
l2ca5:
push bc
ld bc,-8
add hl,bc ; Fix block count
pop bc
ld a,h ; Get hi
or a
ld a,(de)
jp p,l2cb8
l2cb1:
inc l
jr z,l2cbd ; Done, calculate free blocks
or a
rra
jr l2cb1
l2cb8:
call l2cbd ; Calculate free blocks from bits
jr l2ca5
;
; Calculate free blocks in reg BC from vector in Accu
;
l2cbd:
inc de ; Advance allocation vector
l2cbe:
or a ; Test end of bit stream
ret z ; Yeap
rra ; Get resulting bit
jr nc,l2cbe ; Not set
inc bc ; Advance block count
jr l2cbe
;
; Build bytes in blocks
;
l2cc6:
ld a,(l7b71) ; Get block size
l2cc9:
rra ; Get bit
ret c ; Got it
add hl,hl ; Double byte count
jr l2cc9
;
; ################################
; ### MAIN MENUE L - Log drive ###
; ################################
;
l2cce:
call l0200 ; Tell what we expect
;
db 'New drive'
db null
call l2261 ; Input string
ld a,(de)
cp eof ; Test empty input
jr nz,l2ce8 ; Nope
ld a,(DU) ;ok ;FIXME ; Get from caller
jr l2cf1
l2ce8:
call doupcase ; Convert to upper case
sub 'A' ; Verify in range
ret c
cp 'P'-'A'+1
ret nc
l2cf1:
if 1==1
ret
else
push af
ld c,_resdsk
call _BDOS ; Reset disk system
pop af
ld (DU),a ; Set new disk
ld e,a
ld c,_seldsk
jp _BDOS ; Select disk
endif
;
; Ask for YES or NO - Z set is NO
;
l2d01:
call l0200 ; Tell what we does expect
;
db ' (Y/N)? '
db null
l2d0d:
call readfromkbd ; Read character
call doupcase ; Convert to upper case
cp 'Y' ; Test YES
jr z,l2d1b
cp 'N' ; Test NO
jr nz,l2d0d
l2d1b:
call puttoconsole_a ; Put to console
sub 'N'
ret
;
; Get response Y or N - Z set is NO
;
l2d21:
call l2d01 ; Ask for YES or NO
push af
call l01e1 ; Give new line
pop af
ret
;
; Build file <name>.PAS
;
l2d2a:
ld a,'P' ; Set .PAS
ld hl,'A'+'S'*256
l2d2f:
ld (l005c+Fdrv+Fname),a
ld (l005c+Fdrv+Fname+1),hl
ld c,0 ; Set no wild card
call l0406 ; Parse file
ld a,(l005c) ;ok ;FIXME ; Test drive given
or a
ret nz ; Yeap
push de
;ld c,_retdsk
;call _BDOS ; Return current disk (return L=A=current drive)
xor a
inc a
ld (l005c),a ; Set disk
pop de
ret
;
; Test work file defined - Z set says no
;
l2d4b:
ld a,(l451d+Fdrv) ; Fetch name
or a
ret
;
; Get file
;
l2d50:
call l2d4b ; Test work file defined
jr nz,l2d6f ; Yeap
call l2d7a ; Test main file defined
jr nz,l2d5f ; Yeap
call l24c9 ; Get work file
jr l2d6f
l2d5f:
ld de,l451d
ld hl,l44f9 ; Point to main file
ld bc,l0024
ldir
ld a,1
ld (l44f1),a ; Set file flag
l2d6f:
ld a,(l44f1) ; Test file flag
or a
ret z ; No file
call l2602 ; Save work file
jp l2506
;
; Test main file defined - Z set says no
;
l2d7a:
ld a,(l44f9+Fdrv) ; Fetch name
or a
ret
;
; Compare main and work file - Z says same
;
l2d7f:
ld de,l451d ; Point to work file
ld hl,l44f9 ; Point to main file
ld b,Fdrv+Fname+Fext
l2d87:
ld a,(de)
sub (hl) ; Compare
ret nz ; Not same
inc de
inc hl
djnz l2d87
ret
;
; Init session
;
l2d8f:
ld hl,(l4544) ; Get start of text
ld (hl),' ' ; Clear it
inc hl
ld (l4546),hl ; Save pointer
xor a
ld (l447f),a ; Clear text change flag
ld (l44f1),a ; Clear file flag
l2d9f:
xor a
ld (l4542),a ; Force compile
ret
;
; Read error message file
;
l2da4:
ld hl,(l429e) ; Get base of message file
ld (l4544),hl ; Set as start of text
ld de,l217d ; Point to filename
ld a,'M'
ld hl,'S'+'G'*256
call l2e20 ; Prepare .MSG file
ld (l4541),a ; Set error message file read
call z,l2e76 ; Get ESCape
jr z,l2dcf
ld hl,l25a0
ld (l259d+1),hl ; Set vector for file not found
ld hl,l25d4
ld (l257c+1),hl ; Set vector for file too big
ld de,l005c
call l2518 ; Load text file ;closes automatically
l2dcf:
ld hl,(l4546) ; Get end of text
ld (hl),eof
inc hl
ld (l4544),hl ; Set start of text
ret
;
; Convert string ^DE to hex number in reg HL
;
l2dd9:
ld hl,0 ; Init result
l2ddc:
ld a,(de) ; Get character
call doupcase ; Convert to upper case
sub '0' ; Strip off offset
ret c ; Out of range
cp 9+1 ; Test decimal
jr c,l2def ; Yeap
sub 'A'-'0'-10 ; Fix for hex
cp 10 ; Verify correct range
ret c
cp 15+1
ret nc
l2def:
add hl,hl ; Old * 16
add hl,hl
add hl,hl
add hl,hl
or l
ld l,a ; Insert digit
inc de
jr l2ddc
;
; Tell name of file ^DE
;
l2df8:
inc de
ld a,(de) ; Get name
dec de
or a ; Test defined
ret z ; Nope
ld a,(de) ; Get drive
add a,'A'-1
cp 'A'-1 ; Test default drive
call nz,puttoconsole_a ; Put to console if not
ld a,':'
call nz,puttoconsole_a ; Give delimiter
ld b,Fname+Fext ; Set length
l2e0c:
inc de
ld a,(de) ; Get character
and NOMSB ; Strip off attribute
cp ' ' ; Test blank
call nz,puttoconsole_a ; Put to console if not
ld a,b
cp Fext+1 ; Test extension follows
ld a,'.'
call z,puttoconsole_a ; Put delimiter to console if so
djnz l2e0c
ret
;
; Prepare file ^DE with extensin in A,L,H
; Z set if file not found
;
l2e20:
call l2d2f ; Parse file and build extension
ld hl,l005c
call l2e51 ; Open file
ret nz ; Got it
ld a,(l44f8) ; Get logged disk
cp (hl) ; Test same drive
ld (hl),a ; Set logged one
call nz,l2e51 ; Open file if different drives
ret nz
ld a,'A'-'@'
cp (hl) ; Test base drive
ld (hl),a ; Force it
call nz,l2e51 ; Open file if not base
ret nz ; Got it
ld (hl),0 ; Set default drive
ex de,hl ; And tell error
;
; Tell file ^DE not found
;
l2e3e:
call l2df8 ; Tell name of file
call l0200 ; Tell not found
;
db ' not found'
db null
xor a
ret
;
; Open standard file - Z set says not found
;
l2e51:
push de
push hl
ld c,_open
call BDOS_with_FCB1 ; Open file
pop hl
pop de
inc a ; Fix result
ret
;
; Print integer in reg HL fixed sized
;
l2e5c:
ld de,-5 ; Set size
jr l2e64
;
; Print integer number in reg HL
;
l2e61:
ld de,-1 ; Set no size
l2e64:
push ix
push iy
push hl
push de
call l149b ; Set standard device
pop hl
call l1726 ; Write integer
pop iy
pop ix
ret
;
; Get ESCape character
;
l2e76:
push af
call l0200 ; Tell it
;
db '. Press <ESC>'
db null
l2e88:
call readfromkbd ; Read character
jp l0128 ; &PATCH&: Test special keys
nop
l2e8f:
pop af
ret
;
; %%%%%%%%%%%%%%%%%%%%
; %%% EDITOR PART %%%%
; %%%%%%%%%%%%%%%%%%%%
;
l2e91:
push hl
ld de,256*lf+cr
ld hl,(l4546) ; Get end of text
ld (hl),d ; Close line
dec hl
ld (hl),e
ld (l7b74+_LinLen),de
xor a
ld (l4474),a ; Clear change flag
inc a
ld (l4475),a ; Init row
ld hl,l43de
ld (l7b72),hl ; Init pointer to all delimiters
ld iy,l446c
call l023e ; Clear screen
pop de ; Get offset
inc de ; Fix it
ld hl,(l4544) ; Get start of text
add hl,de ; Add to offset
call l33a9 ;status line?
l2ebd:
ld a,(l4482) ; Get control character count
dec a
jr z,l2ed5 ; Got one
ld hl,256*0+0
call l02a2 ; Set cursor to control position
ld a,(l4482) ; Get control character count
add a,a ; Double it
ld b,a ; For count
ld a,' ' ;TODO speedup spaces
l2ed0:
call puttoconsole_a ; Blank control characters
djnz l2ed0
l2ed5:
call l3b96 ;set edit cursor?
call l2ff7 ; Give status
call l2f3a ; Get character
jr nc,l2f0e ; No control
jr z,l2ebd
ld hl,l2ebd
ld a,d
cp (HIGH MMSB)-1 ; Test special address
jr c,l2ef4 ; Nope
ld (l447f),a ; Set text changed
and NOMSB
ld d,a
xor a
ld (l4542),a ; Force compile
l2ef4:
push hl ; Set return address
push de ; Save control address
ld hl,l4456+1
ld de,l445a+1
ld bc,l0008
lddr ; Save a bit
ret
;
; Control: CONTROL PREFIX
;
l2f02::
call l2f8a ; Get character
ld (iy+22),3
call l4271 ; Get character
jr l2f16
l2f0e:
ld (l447f),a ; Re/Set text changed
ld hl,l4542
ld (hl),0 ; Force compile
l2f16:
ld hl,(l4452) ; Get current edit pointer
ld de,l7b74+_LinLen-2
call cmp_hl_de ; Compare HL:DE
jr nc,l2ebd ; Line too long
bit 0,(iy+6) ; Test insert
push af
call z,l41eb ; Yeap, so make room
pop af
ld (hl),a ; Store character
inc hl ; Bump buffer
push hl
call l4197
pop hl
ld (l4452),hl ; Set current edit pointer
call l3fe7 ;set column?
jp l2ebd
;
; Get character
; C set indicates control
;
l2f3a:
call l4271 ; Get character
cp '~'+1 ; Test printable range
jr nc,l2f44 ; Nope
cp ' ' ; Test once again
ret nc
l2f44:
ld hl,l4482 ; Point to control character count
ld (hl),1 ; Init count
inc hl
ld (hl),a ; Save control
l2f4b:
;push hl
;ld hl,l4482 ; Point to control character count
;ld de,l42a1
;ld b,11111111b
;call l2fc1 ; Find control
;pop hl
;or a ; Test found
;jr nz,l2f6b ; Yeap
push hl
ld hl,l4482 ; Point to control character count
ld de,l4369
;ld b,00011111b
ld b,11111111b
call l2fc1 ; Find control
pop hl
or a ; Test found
scf
ret z ; Nope
l2f6b:
dec a ; Test all found
jr z,l2f78 ; Nope
ld hl,l43f4
add hl,bc ; Go into table
add hl,bc
ld e,(hl) ; Fetch address
inc hl
ld d,(hl)
scf ; Set result
ret
l2f78:
call l2f8a ; Get character
push af
call l4271 ; Get character
inc (iy+22)
inc hl
ld (hl),a
pop af
call z,l2f8a ; Get character
jr l2f4b
;
; Get character
;
l2f8a:
call l4232 ; Poll character from input
call l428f ; Test look ahead buffer empty
ret nz ; Nope
push hl
ld hl,256*0+0
call l02a2 ; Position cursor
ld hl,l4482 ; Point to control character count
ld a,(hl) ; Get length
l2f9c:
push af
inc hl
ld a,(hl) ; Get character
call l2fa8 ; Dispaly as control
pop af
dec a
jr nz,l2f9c
pop hl
ret
;
; Display character in Accu
;
l2fa8:
push af
call l3cec ; Make normal video
pop af
cp ' ' ; Test control
jp nc,puttoconsole_a ; Put to console if not
push af
push af
ld a,'^'
call puttoconsole_a ; Indicate control
pop af
add a,'@'
call puttoconsole_a ; Put to console as ASCII
pop af
ret
;
; ^HL points to key sequence searched for in list ^DE with mask in reg B
; Accu= 0 says not found
; Accu= 1 says part found
; Accu=-1 says found
;
l2fc1:
ld c,-1 ; Init index
push bc
push hl
l2fc5:
pop hl
pop bc
ld a,(de) ; Get length from list
inc de
or a ; Test end
ret z ; Yeap
inc c ; Advance index
push bc
push hl
ld c,(hl) ; Get length from input
sub c ; Get difference
inc hl
jr nc,l2fd7 ; In range
add a,c ; Else fix it
ld c,a
jr l2ff0 ; Go adjust
l2fd7:
push af
l2fd8:
ld a,(de) ; Get from list
sub (hl) ; Compare
and b ; Set mask
jr nz,l2fed ; No match
inc de
inc hl
dec c
jr nz,l2fd8
pop af
pop hl
pop bc
ld b,0
ld a,-1
ret z ; Got exact length
ld a,1 ; Fix for partial success
ret
l2fed:
pop af
add a,c
ld c,a
l2ff0:
ld b,0
ex de,hl
add hl,bc
ex de,hl
jr l2fc5
;
; Give editor status
;
l2ff7:
call l4232 ; Poll character from input
call l428f ; Test look ahead buffer empty
ret nz ; Nope
ld hl,l4474
ld a,(hl) ; Test status changed
or a
jr nz,l3078 ; No change
ld (hl),-1 ; Reset it
ld hl,256*0+0
ld (l4476),hl
xor a
ld (l4478),a
call l02a2 ; Position cursor
call l3c12 ; Clear line
call l3cdf ; Set low video
ld a,(l0168) ; Get screen columns
cp MINWID ; Test room for filename
jr c,l302a ; Nope
ld hl,256*42+0
call l02a2 ; Position cursor
call l3135 ; Type work file
l302a:
ld hl,256*6+0
call l420e ; Position cursor and tell line
db 'Line '
db null
ld hl,256*16+0
call l420e ; Position cursor and tell column
db 'Col '
db null
ld hl,256*24+0
ld a,(l4472) ; Get insert mode
or a
jr nz,l305a ; Overwrite
call l420e ; Position cursor and tell insert
db 'Insert '
db null
jr l3068
l305a:
call l420e ; Position cursor and tell overwrite
db 'Overwrite '
db null
l3068:
ld a,(l4479) ; Get tabulate state
or a
jr nz,l3078
call l4211
db 'Indent'
db null
l3078:
ld a,(l446c) ;xscroll???
add a,(iy+4) ; Add column
inc a
ld hl,(l4478)
cp l
jr z,l309b
ld (l4478),a
push af
ld hl,256*20+0
call l02a2 ; Position cursor
call l3cdf ; Set low video
pop af
ld l,a
ld h,0
ld a,3 ; Set number of digits
call l30ec ; Give count
l309b:
ld de,(l4476)
ld hl,(l4450) ; Get current memory pointer
call cmp_hl_de ; Compare HL:DE
jp z,l37a4 ; Same, set edit cursor
call l37a4 ; Set edit cursor
ld de,(l4544) ; Get start of text
ld hl,(l4450) ; Get current memory pointer
or a
sbc hl,de ; Get relative position
ld c,l
ld b,h
ex de,hl
ld de,1
ld a,c
or b ; Test any
jr z,l30d3 ; Nope
l30bf:
ld a,lf
inc de
cpir ; Find new line
jp po,l30d3 ; Got it
dec e
inc e
call z,l4232 ; Poll character from input
call l428f ; Test look ahead buffer empty
jr nz,l30e9 ; Nope
jr l30bf
l30d3:
ld hl,256*11+0
push de
call l02a2 ; Position cursor
call l3cdf ; Set low video
pop hl
ld a,5 ; Set number of digits
call l30ec ; Give count
ld hl,(l4450) ; Get current memory pointer
ld (l4476),hl
l30e9:
jp l37a4 ; Set edit cursor
;
; Print fixed format integer
; ENTRY Reg HL holds number to be printed
; Accu holds decimal places
;
l30ec:
push af
ld b,0 ; Clear count
call l30fe ; Print number
pop af
add a,b ; Test all digits typed
ret z ; Yeap
ld b,a
ld a,' '
l30f8:
call puttoconsole_a ; Fill remainder with blanks
djnz l30f8
ret
;
; Print decimal number
; ENTRY Reg HL holds number
; Reg B holds places
;
l30fe:
ld a,h
or l ; Test zero output
ld a,'0'
jr z,l3131 ; Yeap, print it
ld de,10000
call l311f ; Get ten thousands
ld de,1000
call l311f ; Get thousands
ld de,100
call l311f ; Get hundreds
ld de,10
call l311f ; Get tens
ld de,1 ; Finally units
;
; Print modulo
; ENTRY Reg HL holds number
; Reg DE holds divisor
; Reg B holds places
; EXIT Reg HL fixed
; Reg B decremented if digit is printed
;
l311f:
xor a ; Clear digit
l3120:
sbc hl,de ; Divide
jr c,l3127
inc a ; Bump digit
jr l3120
l3127:
add hl,de ; Make remainder positive
add a,'0' ; Make ASCII
cp '0' ; Test zero
jr nz,l3131
inc b ; Test leading zero
dec b
ret z ; Suppress it
l3131:
dec b ; Fix count
jp puttoconsole_a ; Put to console
;
; Type work file
;
l3135:
ld de,l451d
jp l2df8 ; Tell name of file
;
; Get string for search and file function
; ENTRY Reg DE points to line buffer
; Byte 0 holds max characters
; Byte 1 holds resulting length
;
l313b:
call l0200 ; Indicate input
;
db ': '
db null
ex de,hl
push hl
pop ix ; Copy buffer
inc hl
ld d,(hl)
ld (hl),0
inc hl
l314a:
res _LB,(iy+_Video) ; Disable video
push de
push hl
call l2f3a ; Get character
pop hl
pop de
set _LB,(iy+_Video) ; Allow video
jr nc,l31b9 ; No control
jr nz,l3165
ld a,(l4483) ; Get character
call l3ef6 ; Test function cancelled
jr l314a
l3165:
ld a,c
cp 0
jr nz,l316d
ld (hl),1ah
ret
l316d:
cp 3
jr nz,l317c
ld a,(ix+1)
cp d
jr nc,l314a
inc (ix+1)
jr l31c6
l317c:
cp 5
jr nz,l3190
l3180:
ld a,(ix+1)
cp d
jr z,l314a
ld a,(hl) ; Get character
call l2fa8 ; Display as control
inc hl
inc (ix+1)
jr l3180
l3190:
cp 4
jr nz,l319b
l3194:
call l31d7
jr nz,l3194
jr l314a
l319b:
cp '-'
jr nz,l31a4
call l4271 ; Get character
jr l31b9
l31a4:
cp 1bh
jr z,l31b4
cp 1ch
jr z,l31b4
cp 1
jr z,l31b4
cp 2
jr nz,l314a
l31b4:
call l31d7
l31b7:
jr l314a
l31b9:
ld e,a
ld a,(ix+1)
cp (ix+0)
jr nc,l314a
inc (ix+1)
ld (hl),e
l31c6:
ld a,(hl) ; Get character
inc hl
call l2fa8 ; Display as control
ld a,(ix+1)
cp d
jr c,l31b7
ld d,(ix+1)
jp l31b7
l31d7:
ld a,(ix+1)
or a
ret z
dec (ix+1)
dec hl
ld a,(hl)
cp ' '
call c,l31e6
l31e6:
call l4211
db bs+MSB,' '+MSB,bs+MSB
db null
ld a,0ffh
or a
ret
;
; Control: FIND STRING
;
l31f1:
xor a
ld (l447e),a ; Set find flag
call l31fd ; Get string searched for
call l3220 ; Get options
jr l3252 ; Enter process
;
; Get string searched for
;
l31fd:
call l3e04 ; Tell what we want
db 'Find'
db null
ld de,l4490 ; Point to buffer
l3208:
jp l313b ; Get search string
;
; Get string to be replaced
;
l320b:
call l3e07 ; Tell what we want
db 'Replace with'
db null
ld de,l44b1 ; Point to buffer
jr l3208 ; Get replace string
;
; Get options
;
l3220:
call l3e07 ; Tell what we want
db 'Options'
db null
ld de,l44d2 ; Get buffer
call l313b ; Get search string
ld a,(l0168) ; Get screen columns
ld h,a
dec h ; Fix column
ld l,0 ; Set row
jp l02a2 ; Position cursor
;
; Control: FIND AND REPLACE STRING
;
l323b:
ld a,-1
ld (l447e),a ; Set replace flag
call l31fd ; Get string searched for
call l320b ; Get replace string
call l3220 ; Get options
jr l3252 ; Enter process
;
; Control: REPEAT LAST SEARCH
;
l324b:
call l2f8a ; Get character
ld (iy+22),3 ; Init count
l3252:
call l3e40 ; Sample character
call l3e23 ; Find last non blank
inc hl
ld de,(l4452) ; Get current edit pointer
call l4191 ; Find min
ld de,l7b74
or a
sbc hl,de ; Subtract base
ld de,(l4450) ; Get current memory pointer
add hl,de ; Add for real address
ld (l4488),hl ; Set end
ld de,0 ; Clear counter
ld hl,l44d2+1 ; Init buffer
ld b,(hl) ; Fetch length
ld (iy+17),0 ; Clear flag
inc b ; Test any in buffer
dec b
jr z,l32c0 ; Nope
l327d:
inc hl
ld a,(hl) ; Get character
cp '0' ; Test possible count
jr c,l3293 ; Nope
cp '9'+1
jr nc,l3293
call l3426
sub '0'
add a,e ; Add digit to count
ld e,a
jr nc,l32be
inc d ; Remember carry
jr l32be
l3293:
call doupcase ; Convert to upper case
cp 'W' ; Test whole word search
jr nz,l329e
set _W,(iy+17)
l329e:
cp 'U' ; Test ignore case
jr nz,l32a6
set _U,(iy+17)
l32a6:
cp 'N' ; Test no request
jr nz,l32ae
set _N,(iy+17)
l32ae:
cp 'G' ; Test global
jr nz,l32b6
set _G,(iy+17)
l32b6:
cp 'B' ; Test backwards
jr nz,l32be
set _B,(iy+17)
l32be:
djnz l327d
l32c0:
ld a,e ; Test loop count
or d
jr nz,l32c7 ; Yeap
ld de,1 ; Set default
l32c7:
ld (l448a),de ; Save loop count
ld hl,(l4544) ; Get start of text
ld a,(l447d) ; Get option flags
bit _B,a ; Test backwards
jr z,l32d8 ; Nope
ld hl,(l4546) ; Get end of text
l32d8:
bit _G,a ; Test global search
jr nz,l32df ; Yeap
ld hl,(l4488) ; Get end of search pointer
l32df:
ld (l4488),hl ; Set end of search pointer
bit _B,(iy+17) ; Test backwards
jr nz,l32f5 ; Yeap
ld de,(l4546) ; Get end of text
dec de
call cmp_hl_de ; Compare HL:DE
jp nc,l3380
jr l32fb
l32f5:
call l3bee ; Fix to start of line
jp c,l3380
l32fb:
ld de,l4492
ld a,(l4491)
ld b,a
bit _B,(iy+17) ; Test backwards
jr z,l330e ; Nope
dec a
add a,e
ld e,a
jr nc,l330e
inc d
l330e:
bit _W,(iy+17) ; Test whole word search
jr z,l3323 ; Nope
push de
push hl
call l33fb
ld a,(hl)
pop hl
pop de
jr c,l3323
call l33e4
jr c,l3377
l3323:
dec b
inc b
jr z,l332e
l3327:
call l340f
jr nz,l3377
djnz l3364
l332e:
bit _W,(iy+17) ; Test whole word search
jr z,l3341 ; Nope
push hl
call l3406
ld a,(hl)
pop hl
jr c,l3341
call l33e4
jr c,l3377
l3341:
bit _B,(iy+17) ; Test backwards
call z,l3bdd ; Nope
ld a,(l447e) ; Get find flag
or a
call nz,l3430 ; Replace selected
bit _G,(iy+17) ; Test global search
l3353:
jr nz,l32df
ld bc,(l448a) ; Get loop count
dec bc ; Decrement
ld (l448a),bc
ld a,b
or c
jr nz,l3353
jr l33a9
l3364:
push de
call l3406
pop de
jr c,l3380
bit _B,(iy+17) ; Test backwards
jr z,l3374 ; Nope
dec de
jr l3327
l3374:
inc de
jr l3327
l3377:
ld hl,(l4488) ; Get end of search pointer
call l3406
jp nc,l32df
l3380:
call l33d6
call l33a9
bit _G,(iy+17) ; Test global search
ret nz
call l3e04
db 'Search string not found'
db null
jp l3f12
;status line???
l33a9:
call l33af
jp l3d2c ; Restore line
l33af:
ld de,(l4546) ; Get end of text
dec de
call cmp_hl_de ; Compare HL:DE
jr c,l33ba ;hl<de
ex de,hl
l33ba:
push hl
push hl
call l3bf5 ; Get previous EOL
ld (l4450),hl ; Set current memory pointer
or a
ex de,hl
pop hl
sbc hl,de
ld de,l7b74
add hl,de
ld (l4452),hl ; Set current edit pointer
call l3fe7 ;set column?
call l401f
pop hl
ret
l33d6:
ld de,(l4544) ; Get start of text
call l4191 ; Find min
ld hl,(l4546) ; Get end of text
dec hl
jp l4191 ; Find min
l33e4:
cp '0'
jr c,l33f9
cp ':'
ret c
cp 'A'
jr c,l33f9
cp 5bh
ret c
cp 61h
jr c,l33f9
cp 7bh
ret c
l33f9:
or a
ret
l33fb:
bit _B,(iy+17) ; Test backwards
jr z,l340c ; Nope
l3401:
call l3bdd
ccf
ret
l3406:
bit _B,(iy+17) ; Test backwards
jr z,l3401 ; Nope
l340c:
jp l3bee ; Fix to start of line
l340f:
ld a,(de)
cp 1
ret z
cp (hl)
ret z
bit _U,(iy+17) ; Test ignore case
jr z,l3424 ; Yeap
call l33e4
jr nc,l3424
xor (hl)
and 0dfh
ret
l3424:
cp (hl)
ret
l3426:
push hl
ld l,e
ld h,d
add hl,hl
add hl,hl
add hl,de
add hl,hl
ex de,hl
pop hl
ret
l3430:
push hl
call l428f ; Test look ahead buffer empty
jr z,l343c ; Yeap
bit _N,(iy+17) ; Test no request
jr nz,l349d ; Yeap
l343c:
call l33a9
call l3b96
bit _N,(iy+17) ; Test no request
jr nz,l349d ; Yeap
call l3e07
db 'Replace (','Y'+MSB,'/','N'+MSB,'): '
db null
l345b:
ld l,(iy+5) ; Get row
ld h,(iy+4) ; Get column
call l02a2 ; Position cursor
ld bc,l07d0
l3467:
call l4232 ; Poll character from input
call l428f ; Test look ahead buffer empty
jr nz,l348c ; Nope
dec bc
ld a,c
or b
jr nz,l3467
ld hl,256*15+0
call l02a2 ; Position cursor
ld bc,l07d0
l347d:
call l4232 ; Poll character from input
call l428f ; Test look ahead buffer empty
jr nz,l348c ; Nope
dec bc
ld a,c
or b
jr nz,l347d
jr l345b
l348c:
call l4271 ; Get character
call l3ef6 ; Test function cancelled
call doupcase ; Convert to upper case
cp 'Y'
jr z,l349d
cp 19h
jr nz,l34eb
l349d:
set 0,(iy+19)
xor a
ld (l4542),a ; Force compile
ld a,(l44b2)
ld c,a
ld b,0
pop hl
push hl
push bc
ld a,(l4491)
sub c
ld c,a
push af
jr nc,l34b7
dec b
l34b7:
bit _B,(iy+17) ; Test backwards
jr nz,l34c0 ; Yeap
ld hl,(l4488) ; Get end of search pointer
l34c0:
pop af
push hl
call nz,l3f18
pop de
pop bc
ld a,b
or c
jr z,l34d0
ld hl,l44b3
ldir
l34d0:
call l428f ; Test look ahead buffer empty
push af
call nz,l4147 ; Nope, so reset row
pop af
jr nz,l34e2 ; Eas not empty
push de
call l3d2c ; Restore line
call l4139
pop de
l34e2:
bit _B,(iy+17) ; Test backwards
jr nz,l34eb ; Yeap
pop hl
ex de,hl
ret
l34eb:
pop hl
ret
;
; Control: WRITE BLOCK TO FILE
;
l34ed:
bit 0,(iy+20) ; Test block set
ret nz ; Nope
call l3e40 ; Sample character
call l3d2c ; Restore line
ld hl,(l4460) ; Get block start pointer
ld de,(l4462) ; Get block end pointer
call cmp_hl_de ; Compare HL:DE
ret nc ; Start >= end
call l363c
call l3d2c ; Restore line
l3509:
call l3e04 ; Tell what we want
db 'Write block to file'
db null
call l3566 ; Get name of file
ret z
call l2d2a ; Prepare .PAS file
ld c,_open
call BDOS_with_FCB1 ; Open file ;WHERE IS CLOSE???
inc a ; Test file already exist
jr z,l3551 ; Nope
call l3e07
db 'Overwrite old '
db null
ld de,l005c
call l2df8 ; Tell name of file
call l2d01 ; Ask for YES or NO
jr z,l3509 ; No
ld c,_delete
call BDOS_with_FCB1 ; Delete file
l3551:
ld hl,(l4462) ; Get block end pointer
ld a,(hl) ; Save character
push af
push hl
ld (hl),eof ; Set end of file
call l3e0d ; Set cursor
ld hl,(l4460) ; Get block start pointer
call l2692 ; Save block to file
ld c,_close
call BDOS_with_FCB1
pop hl
pop af
ld (hl),a ; Restore character
ret
;
; Get name of file
;
l3566:
ld de,l44df
call l313b ; Get filename
ld de,l44df+2
ld a,(de)
cp eof ; Test empty name
ret
;
; Control: READ BLOCK FROM FILE
;
l3573:
call l3e04 ; Tell what we want
db 'Read block from file'
db null
call l3566 ; Get name of file
ret z
call l2d2a ; Prepare .PAS file
ld c,_open
call BDOS_with_FCB1 ; Open file ;WHERE IS CLOSE???
inc a ; Test success
jr nz,l35a8 ; Yeap
call l3e0d ; Set cursor
ld de,l005c
call l2e3e ; Tell not found
call l3f12
jr l3573
l35a8:
res 0,(iy+20) ; Mark block
call l363c
ld hl,(l4546) ; Get end of text
ld de,(l4548) ; Get top of available memory
ld bc,l00fe
add hl,bc ; Build top
or a
sbc hl,de ; Calculate size
push hl
ld b,h
ld c,l
ld hl,(l448c)
scf
call l3f18
ld c,_close
call BDOS_with_FCB1
pop de
ld hl,l35dd ; Set return address
push hl
ld hl,(l448c)
push hl
xor a
sbc hl,de
push hl
ld hl,l35f1
ld (l257c+1),hl ; Redirect load error
jp l2560 ; Load the block
;
; Process end of read
;
l35dd:
ld (l4462),hl ; Set block end pointer
ex de,hl
ld hl,(l448c)
ld (l4460),hl ; Set block start pointer
l35e7:
ld hl,(l7b6d) ; Get last memory address
or a
sbc hl,de ; Build difference
ld b,h
ld c,l
jr l3612
;
; Redirected load error
;
l35f1:
ld de,(l448c)
call l35e7
jp l3ed9
;
; Control: MOVE BLOCK
;
l35fb:
call l363c
jp nc,l3d2c ; Restore line
call l3687
ld hl,(l448c)
ld de,(l4460) ; Get block start pointer
ld (l4460),hl ; Set block start pointer
add hl,bc
ld (l4462),hl ; Set block end pointer
l3612:
ex de,hl
or a
call l3f18
ld hl,(l4460) ; Get block start pointer
call l33a9
jp l3762
;
; Control: COPY BLOCK
;
l3620:
call l363c
jp nc,l3d2c ; Restore line
call l3687
ld hl,(l448c)
ld (l4460),hl ; Set block start pointer
add hl,bc
ld (l4462),hl ; Set block end pointer
call l401f
call l3d2c ; Restore line
jp l3762
;
;
;
l363c:
bit 0,(iy+20) ; Test block set
jr z,l3644 ; Yeap
xor a
ret
l3644:
call l3e23 ; Find last non blank
inc hl
ld de,(l4452) ; Get current edit pointer
push de
call l4191 ; Find min
ex de,hl
call l3e44 ; Sample character
pop hl
ld de,l7b74
or a
sbc hl,de ; Subtract base
ld de,(l4450) ; Get current memory pointer
add hl,de ; Build real pointer
ld (l448c),hl
push hl
ld de,(l4460) ; Get block start pointer
inc de
call cmp_hl_de ; Compare HL:DE
ld de,(l4462) ; Get block end pointer
jr c,l367a ; HL < Start_Of_Block
call cmp_hl_de ; Compare HL:DE
jr nc,l367a ; HL >= End_Of_Block
or a
jr l3685
l367a:
ld hl,(l4460) ; Get block start pointer
or a
sbc hl,de
ld (l448e),hl
ld c,l
ld b,h
l3685:
pop hl
ret
;
;
;
l3687:
call l3f18
ld bc,(l448e)
ld a,c ; Negate value
cpl
ld c,a
ld a,b
cpl
ld b,a
inc bc
ld de,(l448c)
ld hl,(l4460) ; Get block start pointer
push bc
ldir
pop bc
ret
;
; Control: DELETE BLOCK
;
l36a1:
bit 0,(iy+20) ; Test block set
ret nz ; Nope
call l3e40 ; Sample character
ld hl,(l4460) ; Get block start pointer
call l3bf5 ; Get previous EOL
ld (l4450),hl ; Set current memory pointer
ld hl,(l4454) ; Get block pointer
ld de,(l4460) ; Get block start pointer
inc de
call cmp_hl_de ; Compare HL:DE
jr c,l36ce ; HL < Start_Of_Block
ld de,(l4462) ; Get block end pointer
call cmp_hl_de ; Compare HL:DE
jr nc,l36ce ; HL >= End_Of_Block
ld hl,(l4450) ; Get current memory pointer
ld (l4454),hl ; Set block pointer
l36ce:
ld hl,(l4462) ; Get block end pointer
ld de,(l4460) ; Get block start pointer
or a
sbc hl,de
jp c,l3d2c ; Restore line if End < Start
ld c,l
ld b,h
ex de,hl
push hl
push bc
push af
call l401f
pop af
pop bc
pop hl
call l3f18
ld hl,(l4450) ; Get current memory pointer
ld (l4460),hl ; Set block start pointer
ld (l4462),hl ; Set block end pointer
call l3d2c ; Restore line
jp l3762
;
; Control: TOGGLE BLOCK DISPLAY
;
l36f9:
ld hl,l4480 ; Point to block mark
call l3796 ; Toggle block bit
jp l3762
;
; Control: MARK END OF BLOCK
;
l3702:
ld hl,(l4452) ; Get current edit pointer
ld (l4466),hl ; Set for end of block
ld hl,(l4450) ; Get current memory pointer
ld (l4462),hl ; Set block end pointer
bit 1,(iy+1) ; Test end block
set 1,(iy+1)
l3716:
ex af,af'
bit 0,(iy+20) ; Test previous block set
res 0,(iy+20) ; Set now
jr nz,l3762 ; Was not set
ex af,af'
jr z,l3762 ; Prevous was also not set
jr l374e
;
; Control: MARK BEGIN OF BLOCK
;
l3726:
ld hl,(l4452) ; Get current edit pointer
ld (l4464),hl ; Save address
ld hl,(l4450) ; Get current memory pointer
ld (l4460),hl ; Set block start pointer
bit 0,(iy+1) ; Test start block
set 0,(iy+1)
jr l3716
;
; Control: BEGIN OF BLOCK
;
l373c:
call l3e40 ; Sample character
ld hl,(l4460) ; Get block start pointer
jp l33a9
;
; Control: END OF BLOCK
;
l3745:
call l3e40 ; Sample character
ld hl,(l4462) ; Get block end pointer
jp l33a9
;
;
;
l374e:
ld h,0 ; Set left column
call l37a7 ; Set editor cursor
ld hl,l7b74 ; Load base address
set 0,(iy+16)
call l3c1a
res 0,(iy+16)
ret
;
;
;
l3762:
call l374e
jp l4147 ; Reset row
;
; Control: END OF TEXT
;
l3768:
call l3e40 ; Sample character
ld hl,(l4546) ; Get end of text
jp l33a9
;
; Control: LINE LEFT
;
l3771:
ld hl,l7b74 ; Set start of line
ld (l4452),hl ; Set current edit pointer
jp l3fe7 ;set column?
;
; Control: LINE RIGHT
;
l377a:
call l3e23 ; Find last non blank
inc hl
ld de,l7b74+_LinLen
call cmp_hl_de ; Compare HL:DE
jr c,l3789
ld hl,l7b74+_LinLen-1
l3789:
ld (l4452),hl ; Set current edit pointer
jp l3fe7 ;set column?
;
; Control: TOGGLE INSERT/OVERWRITE
;
l378f:
ld (iy+8),0 ; Set no change
ld hl,l4472 ; Point to insert mode
;
; Toggle status bit ^HL
;
l3796:
ld a,(hl) ; Get value
xor 1 ; Toggle bit
ld (hl),a
ret
;
; Control: TOGGLE TABULATE
;
l379b:
ld (iy+8),0 ; Set no change
ld hl,l4479
jr l3796 ; Toggle tabulate bit
;
; Set current edit cursor
;
l37a4:
ld h,(iy+4) ; Get column
;
; Set editor cursor to current row
; ENTRY Reg H holds column position
;
l37a7:
ld l,(iy+5) ; Get row
jp l02a2 ; Position cursor
;
; Control: LINE DOWN
;
l37ad:
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
ret c ; Out of text
call l3e40 ; Sample character
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
l37bd:
ld (l4450),hl ; Set current memory pointer
res 0,(iy+14)
set 0,(iy+21)
call l401f
res 0,(iy+21)
jp l3d2c ; Restore line
;
; Control: LINE UP
;
l37d2:
ld hl,(l4450) ; Get current memory pointer
call findprevline ; Find previous line
ret c ; Below start of text
push hl
call l3e40 ; Sample character
pop hl
jr l37bd
;
; Control: SCROLL UP
;
l37e0:
ld hl,(curstartofpage) ; Get start of screen
ld de,(l4544) ; Get start of text
call cmp_hl_de ; Compare HL:DE
ret z
call l3e40 ; Sample character
ld b,0
ld hl,(l4450) ; Get current memory pointer
l37f3:
ld de,(curstartofpage) ; Get start of screen
call cmp_hl_de ; Compare HL:DE
jr z,l3802 ; Match
call findprevline ; Find previous line
inc b
jr l37f3
l3802:
ld de,(l4450) ; Get current memory pointer
ld (l4450),hl ; Set current memory pointer
ex de,hl
ld a,(l0169) ; Get screen lines
sub 3 ; Less status
cp b
jr nz,l3815
call findprevline ; Find previous line
l3815:
push hl
ld hl,(l4450) ; Get current memory pointer
call findprevline ; Find previous line
call l37bd
pop hl
l3820:
jr l37bd
;
; Control: SCROLL DOWN
;
l3822:
call l3e40 ; Sample character
ld hl,(l4450) ; Get current memory pointer
push hl
ld hl,(curstartofpage) ; Get start of screen
ld a,(l0169) ; Get screen lines
sub 2 ; Less status
ld b,a
l3832:
call findnexteol ; Find next end of line
djnz l3832
push af
call l37bd
pop af
pop hl
jr c,l3820
ld de,(curstartofpage) ; Get start of screen
call cmp_hl_de ; Compare HL:DE
jr nc,l3820 ; HL >= Start_Of_Screen
call findnexteol ; Find next end of line
jr l3820
;
; Control: BOTTOM OF SCREEN
;
l384d:
ld hl,(curstartofpage) ; Get start of screen
ld de,(l4450) ; Get current memory pointer
call cmp_hl_de ; Compare HL:DE
ret z ; Same
push hl
call l3e40 ; Sample character
pop hl
jr l3820
;
; Control: TOP OF SCREEN
;
l385f:
call l3e40 ; Sample character
ld hl,(curstartofpage) ; Get start of screen
ld a,(l0169) ; Get screen lines
sub 3 ; Less status
ld b,a
l386b:
call findnexteol ; Find next end of line
djnz l386b
jr l3820
;
; Control: PAGE DOWN
;
l3872:
call l3e40 ; Sample character
ld a,(l0169) ; Get screen lines
sub 2 ; Less status
ld c,a
ld b,a
ld hl,(curstartofpage) ; Get start of screen
l387f:
call findnexteol ; Find next end of line
djnz l387f
ld (curstartofpage),hl ; Set start of screen
ld b,c
ld hl,(l4450) ; Get current memory pointer
l388b:
call findnexteol ; Find next end of line
djnz l388b
l3890:
ld (l4450),hl ; Set current memory pointer
call l401f
call l4147 ; Reset row
jp l3d2c ; Restore line
;
; Control: PAGE UP
;
l389c:
call l3e40 ; Sample character
ld a,(l0169) ; Get screen lines
sub 2 ; Less status
ld b,a
ld c,a
ld hl,(curstartofpage) ; Get start of screen
l38a9:
call findprevline ; Find previous line
djnz l38a9
ld (curstartofpage),hl ; Set start of screen
ld b,c
ld hl,(l4450) ; Get current memory pointer
l38b5:
call findprevline ; Find previous line n-times
djnz l38b5
jr l3890
;
; Control: BEGIN OF TEXT
;
l38bc:
ld hl,(curstartofpage) ; Get start of screen
ld de,(l4544) ; Get start of text
call cmp_hl_de ; Compare HL:DE
jr z,l38cb ; Same
call l4147 ; Reset row
l38cb:
call l3e40 ; Sample character
ld hl,(l4544) ; Get start of text
ld (l4450),hl ; Set current memory pointer
ld (curstartofpage),hl ; Set start of screen
call l401f
call l3d2c ; Restore line
ld hl,l7b74
ld (l4452),hl ; Init edit pointer
jp l3fe7 ;set column?
;
; Control: NEW LINE
;
l38e6:
bit 0,(iy+6) ; Test insert
jr z,l38f2 ; New line
call l37ad ; Line down
jp l3771 ; Goto start of line
l38f2:
set 0,(iy+19)
xor a
ld (l4542),a ; Force compile
ld a,lf
call puttoconsole_a ; Put new line to console
call l3918
call l37a4 ; Set edit cursor
bit 0,(iy+13) ; Test auto tab
ret nz ; Yeap
call l3a6b ; Position to previous line
ret c ; Below start of text
ld de,l43f2
call l412e ; Find blank
jp c,l3a72 ; Yeap, insert tab
ret
;
;
;
l3918:
call l3950
ld hl,(l4450) ; Get current memory pointer
push hl
call l3d2c ; Restore line
call l3e40 ; Sample character
pop hl
call findnexteol ; Find next end of line
ld (l4450),hl ; Set current memory pointer
ld hl,l7b74
l392f:
ld (l4452),hl ; Set current edit pointer
call l3fe7 ;set column?
call l401f
jp l3d2c ; Restore line
;
; Control: INSERT LINE
;
l393b::
call l3950
call l0200
db cr,lf,null
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
call l3c1a
jp l3d2c ; Restore line
;
;
;
l3950:
call l3e40 ; Sample character
ld a,(l01ae) ; Test insert line implemented
or a
push af
call nz,l0262 ; Yeap: insert line
pop af
call z,l4139 ; Nope
call l3e23 ; Find last non blank
inc hl ; Skip
ld de,(l4452) ; Get current edit pointer
call l4191 ; Find min
ld de,l7b74
or a
sbc hl,de ; Subtract base
l3970:
ex de,hl
ld hl,(l4450) ; Get current memory pointer
add hl,de ; Add offset
push hl
scf
ld bc,-2
call l3f18
pop hl
ld (hl),cr ; Close line
inc hl
ld (hl),lf
ret
;
; Control: CURSOR LEFT
;
l3984:
ld hl,(l4452) ; Get current edit pointer
call l3c02 ; move character left
ret c ; Not possible
l398b:
ld (l4452),hl ; Set current edit pointer
jp l3fe7 ;set column?
;
; Control: CURSOR RIGHT
;
l3991:
ld hl,(l4452) ; Get current edit pointer
call l3be8 ; move character right
ret nc ; Out off limit
jr l398b ; Save new position
;
; Control: LAST CURSOR POSITION
;
l399a:
call l3e40 ; Sample character
ld hl,(l4458) ; Get edit pointer
call l3bf5 ; Get previous EOL
ld (l4450),hl ; Set current memory pointer
ld hl,(l445a)
jp l392f
;
; Control: MARK SINGLE WORD
;
l39ac:
call l3a0b ; Word right
call l39ea ; Word left
ld hl,(l4452) ; Get current edit pointer
l39b5:
call l412a ; Find delimiter
jr c,l39bf ; Yeap
call l3be8 ; move character right
jr c,l39b5 ; Still in limit
l39bf:
ld (l4452),hl ; Set current edit pointer
call l3702 ; Mark end
call l39ea ; Word left
jp l3726 ; Mark start
;
;
;
l39cb:
ld hl,(l4450) ; Get current memory pointer
call findprevline ; Find previous line
jr c,l3a05 ; Below start
push hl
call l3e40 ; Sample character
pop hl
ld (l4450),hl ; Set current memory pointer
res 0,(iy+14)
call l401f
call l3d2c ; Restore line
call l3e23 ; Find last non blank
jr l3a01
;
; Control: WORD LEFT
;
l39ea:
ld hl,(l4452) ; Get current edit pointer
l39ed:
call l3c02 ; move character left
jr c,l39cb ; At beginning of line
call l412a ; Find delimiter
jr c,l39ed ; Yeap
l39f7:
call l3c02 ; move character left
jr c,l3a01 ; At beginning of line
call l412a ; Find delimiter
jr nc,l39f7 ; Nope
l3a01:
inc hl
l3a02:
ld (l4452),hl ; Set current edit pointer
l3a05:
ld hl,(l4452) ; Get current edit pointer
jp l3fe7 ;set column?
;
; Control: WORD RIGHT
;
l3a0b:
call l3e23 ; Find last non blank
ld de,(l4452) ; Get current edit pointer
push de
xor a
sbc hl,de
jr nc,l3a19
inc a
l3a19:
ld (l7b71),a ; Set direction flag
pop hl
l3a1d:
dec hl
l3a1e:
call l3be8 ; move character right
jr c,l3a4e ; Still in limit
l3a23:
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
ret c ; Out of text
call l3e40 ; Sample character
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
ld (l4450),hl ; Set current memory pointer
res 0,(iy+14)
call l401f
call l3d2c ; Restore line
ld hl,l7b74
ld (l4452),hl ; Init current edit pointer
call l412a ; Find delimiter
jr c,l3a1d ; Yeap
jp l3fe7 ;set column?
l3a4e:
call l412a ; Find delimiter
jr nc,l3a1e ; Nope
l3a53:
call l3be8 ; move character right
jr c,l3a64 ; Still in limit
ld a,(l7b71) ; Get direction
or a
jr nz,l3a23
call l3e23 ; Find last non blank
inc hl ; Skip
jr l3a02
l3a64:
call l412a ; Find delimiter
jr c,l3a53 ; Yeap
jr l3a02
;
; Position to previous line
; EXIT Reg HL points to line
; Carry set if below start of text
;
l3a6b:
ld hl,(l4450) ; Get current memory pointer
call findprevline ; Find previous line
ret
;
; Control: TABULATE
;
l3a72:
call l3a6b ; Position to previous line
ret c ; Below start of text
ld a,(l4471) ; Get row
push af ; Save it
ld hl,(l4452) ; Get current edit pointer
ld (l4468),hl ; Save it
res 0,(iy+7) ; Disable video
call l3e40 ; Sample character
ld hl,(l4450) ; Get current memory pointer
push hl
call findprevline ; Find previous line
ld (l4450),hl ; Set current memory pointer
call l3d2c ; Restore line
ld hl,l43f2
ld (l7b72),hl ; Set pointer to reduced delimiters
call l3a0b ; Word right
ld hl,l43de
ld (l7b72),hl ; Reset pointer to delimiters
pop hl
pop af
ld (l4471),a ; Reset row
ld (l4450),hl ; Reset current memory pointer
call l3d2c ; Restore line
set 0,(iy+7) ; Enable video
bit 0,(iy+6) ; Test insert
jp nz,l374e ; Nope
ld hl,(l4452) ; Get current edit pointer
ld de,(l4468) ; Get back previous pointer
sbc hl,de ; Get difference
ret c ; Nothing to clear
ret z
ex de,hl ; Get length
l3ac5:
push de
call l41eb ; Make room
ld (hl),' ' ; Insert blank
pop de
dec e
jr nz,l3ac5
jp l374e
;
; Control: DELETE TO END OF LINE
;
l3ad2:
ld hl,(l4452) ; Get current edit pointer
push hl
call l3fc5
pop hl
push hl
ld de,l7b74+_LinLen-1
l3ade:
ld (hl),' ' ; Clear character
call cmp_hl_de ; Compare HL:DE
jr z,l3ae8 ; Match
inc hl ; Advance
jr l3ade
l3ae8:
pop hl
jp l4197
;
; Control: DELETE LINE
;
l3aec::
ld hl,l7b74
ld (l4452),hl ; Set current edit pointer
call l3fe7 ;set column?
call l3ad2 ; Delete to end of line
call l3e40 ; Sample character
ld hl,(l4450) ; Get current memory pointer
push hl
push hl
call findnexteol ; Find next end of line
pop de
jr c,l3b10 ; Out of text
or a
sbc hl,de ; Fet length
ld c,l
ld b,h
pop hl
jp nz,l3b26
ret
l3b10:
pop hl
jp l3d2c ; Restore line
l3b14:
call l3e44 ; Sample character
ld hl,(l4450) ; Get current memory pointer
call findnexteol ; Find next end of line
jp c,l3d2c ; Restore line if out of text
dec hl
dec hl
ld bc,2
or a
l3b26:
call l3f18
ld a,(l01b4) ; Test delete line implemented
or a
jr z,l3b3c ; Nope
call l0259 ; Delete line
ld a,(l0169) ; Get screen lines
dec a
call l3bbc
jp l3d2c ; Restore line
l3b3c:
call l4139
jp l3d2c ; Restore line
;
; Control: DELETE RIGHT WORD
;
l3b42:
call l3e23 ; Find last non blank
ld de,(l4452) ; Get current edit pointer
call cmp_hl_de ; Compare HL:DE
ex de,hl
jr c,l3b14 ; HL<DE
ld a,(hl)
cp ' ' ; Test blank
jr z,l3b8c
call l412a ; Find delimiter
jr c,l3b83 ; Yeap
l3b59:
call l4173
call l412a ; Find delimiter
jr c,l3b86 ; Yeap
jr l3b59
;
;
;
l3b63:
ld hl,(l4450) ; Get current memory pointer
call findprevline ; Find previous line
ret c ; Below start of text
call l37d2 ; Line up
call l377a ; Line right
jp l3b42 ; Delete right word
;
; Control: DELETE RIGHT CHARACTER
;
l3b73:
ld hl,(l4452) ; Get current edit pointer
jr l3b83 ; Go delete
;
; Control: DELETE LEFT CHARACTER
;
l3b78:
ld hl,(l4452) ; Get current edit pointer
call l3c02 ; move character left
jr c,l3b63 ; Beginning of line
ld (l4452),hl ; Set current edit pointer
l3b83:
call l4173
l3b86:
call l3fe7 ;set column?
jp l4197
l3b8c:
call l4173
ld a,(hl)
cp ' ' ; Test blank
jr z,l3b8c ; Skip them
jr l3b86
;
;
;
l3b96:
call l428f ; Test look ahead buffer empty
jp nz,l37a4 ; Nope, set edit cursor
call l3bac
jr nc,l3b96
jp l37a4 ; Set edit cursor
;
;
;
l3ba4:
call l3bac
jr nc,l3ba4
jp l37a4 ; Set edit cursor
;
; ????????????????????????????????????????????
; EXIT Carry set if row same as screen height
;
l3bac:
ld a,(l4475) ; Get current row
ld hl,l0169 ; Get screen lines
cp (hl) ; Compare
scf
ret z ; Same, so exit
inc (iy+9) ; Bump row
cp (iy+5) ; Test aginst row
ret z
;
;
;
l3bbc:
ld h,0 ; Set column
ld l,a ; Get row
push af
call l02a2 ; Position cursor
pop af
ld hl,(curstartofpage) ; Get start of screen
ld b,a
l3bc8:
dec b
jr z,l3bd8
call findnexteol ; Find next end of line
jr nc,l3bc8
call l3cec ; Make normal video
call l3c12 ; Clear line
xor a
ret
l3bd8:
call l3c1a
xor a
ret
;
;
;
l3bdd:
;gotonextchar,check eof
inc hl
ld de,(l4546) ; Get end of text
;
; Compare addresses
; ENTRY Regs HL and DE hold addresses
; EXIT Zero set if HL=DE
; Carry set if HL<DE
;
cmp_hl_de:
push hl
or a
sbc hl,de ; Compare
pop hl
ret
;
; move pointer right
; ENTRY Reg HL holds pointer
; EXIT Carry reset if pointer ou of limit
;
l3be8:
inc hl ; Point to next
ld de,l7b74+_LinLen-2
jr cmp_hl_de ; Compare HL:DE
;
; Fix to start of line
; ENTRY Reg HL holds text pointer
; EXIT Reg HL decremented by 1
; Carry set if HL < Start_of_Text
;
l3bee:
dec hl
ld de,(l4544) ; Get start of text
jr cmp_hl_de ; Compare HL:DE
;
; Find EOL of previous line
; ENTRY Reg HL holds current pointer
; EXIT Reg HL points to previous end
;
l3bf5:
ld a,lf
l3bf7:
call l3bee ; Fix to start of line
ret z ; Got it
jr c,l3c00 ; Here before start
cp (hl) ; Find new line
jr nz,l3bf7 ; Nope
l3c00:
inc hl ; Adjust pointer
ret
;
; move pointer left
; ENTRY Reg HL holds pointer
; EXIT Carry set if pointer out of limit
;
l3c02:
dec hl ; Get previous
ld de,l7b74 ; Init pointer
jr cmp_hl_de ; Compare HL:DE
;
;
;
l3c08:
;nextline
cp cr ; Test return
ret nz ; Nope
ld a,(hl)
call l3bdd ;gotonextchar,check eof
ret nc ;eof
jr l3c08
;
; Clear line
;
l3c12:
ld a,(l0168) ; Get screen columns
dec a
ld b,a
l3c17:
jp l3cf9 ; Clear to end of line
;
;
;
l3c1a:
call l3ca1
call l3cc0
ld a,(l446c) ;xscroll???
ld b,a
or a
jr z,l3c36
l3c27:
ld a,(hl)
call l3bdd
jr nc,l3c12 ; Clear line
call l3c08 ;nextline (hl after cr)
cp lf ; Test new line
jr z,l3c12 ; Clear line if so
djnz l3c27 ;skip xscroll chars???
l3c36:
ld a,(l0168) ; Get screen columns
dec a
ld b,a
bit 0,(iy+16)
jr z,l3c5e
l3c41:
call l3ca1
call l3cc0
push hl
call l3e23 ; Find last non blank
ld de,(l4452) ; Get current edit pointer
call l4191 ; Find min
ex de,hl ; Change to max
inc hl
ld (l4486),hl
ex de,hl
pop hl
call cmp_hl_de ; Compare HL:DE
jr nc,l3c89 ; Clear if HL>=DE
l3c5e:
call l3ca1
call l3cc0
ld de,(l4486)
call cmp_hl_de ; Compare HL:DE
jr z,l3c89 ; Clear if same
ld a,(hl)
call l3bdd ;gotonextchar,check eof
jr nc,l3c17 ; Clear line
call l3c08 ;nextline (hl after cr)
cp lf ; Test end of line
jr z,l3c17 ; Clear on new line
call l3c8b ; Process control character
djnz l3c5e
l3c7f:
ld a,(hl)
call l3bdd
jr nc,l3c89 ; Clear line
cp lf ; Test new line
jr nz,l3c7f
l3c89:
jr l3c17 ; Clear line
;
; Process control character
;
l3c8b:
cp ' ' ; Test control character
jr nc,l3c96 ; Nope
add a,'@' ; Make ASCII
push af
call l3c99 ; Select video
pop af
l3c96:
jp puttoconsole_a ; Put to console ;TODO speedup
;
; Select video
;
l3c99:
ld a,(l00e0) ;ok ;FIXME ; Get video mode
or a
jr z,l3cec ; Make normal video
jr l3cdf ; Set low video
;
;
;
l3ca1:
bit 0,(iy+16)
ret z
bit 0,(iy+20) ; Test block set
jr nz,l3cec ; Nope, make normal video
ld de,(l4464) ; Get block start address
call cmp_hl_de ; Compare HL:DE
jr c,l3cec ; Make normal video
ld de,(l4466) ; Get end of block pointer
call cmp_hl_de ; Compare HL:DE
jr c,l3cdf ; Set low video
jr l3cec ; Make normal video
;
;
;
l3cc0:
bit 0,(iy+16)
ret nz
bit 0,(iy+20) ; Test block set
jr nz,l3cec ; Nope, make normal video
ld de,(l4460) ; Get block start pointer
call cmp_hl_de ; Compare HL:DE
jr c,l3cec ; Make normal video
ld de,(l4462) ; Get block end pointer
call cmp_hl_de ; Compare HL:DE
jr z,l3cec ; Make normal video
jr nc,l3cec ; Make normal video
;
; Set low video
;
l3cdf:
ld a,(l00e0) ;ok ;FIXME ; Get video mode
or a ; Test enabled
ret z ; Nope
bit 0,(iy+7) ; Test selected
ret z ; Nope
jp setlowvideo ; Set low video
;
; Set normal video
;
l3cec:
ld a,(l00e0) ;ok ;FIXME ; Get video mode
or a ; Test enabled
ret nz ; Yeap
bit 0,(iy+7) ; Test selected
ret z ; Nope
jp setnormvideo ; Set normal video
;
; Clear to end of line
; ENTRY Reg B holds column position
;
l3cf9:
inc b ; Test position
dec b
ret z ; Ignore left margin
ld a,(l01bc) ; Test clear to end of line implemented
or a
jp nz,l0299 ; Yeap
l3d03:
ld a,' '
call puttoconsole_a ; Put blanks to console
djnz l3d03
ret
;
; Delete current line
;
l3d0b:
ld a,(l01b4) ; Test delete line implemented
or a
jr nz,l3d23 ; Yeap
ld (l4474),a ; Set no change
ld a,(l0169) ; Get screen lines
dec a
ld l,a ; Set row
ld h,0 ; Set column
call l02a2 ; Position cursor
ld a,lf
jp puttoconsole_a ; Put new line to console
l3d23:
ld hl,256*0+1
call l02a2 ; Position cursor
jp l0259 ; Delete line
;
; Control: RESTORE DELETED LINE
;
l3d2c:
ld hl,(l4450) ; Get current memory pointer
ld de,0
ld (l4464),de ; Reset start of block pointer
ld (l4466),de ; Reset end of block pointer
ld b,_LinLen ; Set max length
ld ix,l7b74 ; Set base address
ld (iy+1),0 ; Clear block state
l3d44: ;;;;;;
ld a,(hl)
ld de,(l4460) ; Get block start pointer
call cmp_hl_de ; Compare HL:DE
jr nz,l3d56 ; Not same addresses
ld (l4464),ix ; Set start of block pointer
set 0,(iy+1) ; Set start block
l3d56:
ld de,(l4462) ; Get block end pointer
call cmp_hl_de ; Compare HL:DE
jr nz,l3d67 ; Not same addresses
ld (l4466),ix ; Set end of block pointer
set 1,(iy+1) ; Set end block
l3d67:
cp cr ; Test end of line
jr nz,l3dc3 ; Nope
ld (ix+0),' ' ; Fill with blank
inc ix
dec b
jr z,l3dd9
call l3bdd
jr nc,l3d44
l3d79:
ld de,(l4462) ; Get block end pointer
call cmp_hl_de ; Compare HL:DE
jr nc,l3d8a ; HL>= Start_Of_Block
push hl
ld hl,-1
ld (l4466),hl ; Set end of block pointer
pop hl
l3d8a:
ld de,(l4460) ; Get block start pointer
call cmp_hl_de ; Compare HL:DE
jr nc,l3d99 ; HL>= End_Of_Block
ld hl,-1
ld (l4464),hl ; Set start of block pointer
l3d99: ;;;;;
ld a,_LinLen
sub b ; Calculate remaining length
ld (l446f),a ; Save relative column
l3d9f:
ld (ix+0),' ' ; Fill with blanks
inc ix
djnz l3d9f
ld hl,(l4452) ; Get current edit pointer
call l3fe7 ;set column?
bit 0,(iy+14)
set 0,(iy+14)
jp nz,l374e
ld a,(l4475) ; Get current row
dec a
cp (iy+5) ; Test against row
ret nc
jp l374e
l3dc3:
cp lf ; Test end of line
jr z,l3d79 ; Yeap
ld (ix+0),a ; Store character
inc ix
dec b ; Test still room
jr nz,l3dd1 ; Yeap
jr l3dd9 ; Line too long
l3dd1:
call l3bdd
jr nc,l3d79
jp l3d44
l3dd9:
call l3e04 ; Tell error
db 'Line too long - CR inserted'
db null
call l3f12
ld hl,_LinLen-2
call l3970
jp l3d2c ; Restore line
;
;
;
l3e04:
call l3ba4
l3e07:
call l3e0d ; Set cursor
jp l4211
;
; Set cursor home
;
l3e0d:
ld (iy+8),0 ; Set no change
ld hl,256*0+0
call l02a2 ; Position cursor
call l3c12 ; Clear line
ld hl,256*0+0
call l02a2 ; Position cursor
jp l3cdf ; Set low video
;
; Find last non blank in current line
; EXIT Reg HL holds pointer to non blank
;
l3e23:
ld a,' ' ; Set what we are looking for
ld hl,l7b74+_LinLen-1
ld de,l7b74-1 ; Init pointers
l3e2b:
cp (hl) ; Test match
ret nz ; Nope, got it
dec hl
call cmp_hl_de ; Test beginning
jr nz,l3e2b ; Nope
ret
;
; Get pointer within limits
; ENTRY Reg HL holds 1st pointer
; Reg BC holds 2nd pointer
; EXIT Reg HL unchanged if out of line
; Reg HL holds MIN(HL,BC) else
;
l3e34:
ld de,l7b74+_LinLen
call cmp_hl_de ; Compare HL:DE
ret nc ; End found
ld d,b
ld e,c
jp l4191 ; Find min
;
; Poll character, insert at end of line
;
l3e40:
call l3e23 ; Find last non blank
inc hl ; Skip over
;
; Poll character, insert at current position
; ENTRY Reg HL holds current text address
;
l3e44:
ld c,l ; Copy pointer
ld b,h
ld hl,(l4464) ; Get start of block pointer
call l3e34 ; Fix it
ld (l4464),hl ; Set start of block pointer
ld hl,(l4466) ; Get end of block pointer
call l3e34 ; Fix it
ld (l4466),hl ; Set end of block pointer
ld l,c
ld h,b
inc hl
ld de,l7b74
or a
sbc hl,de ; Get relative position
push hl
ld a,(l446f) ; Get relative column
sub l ; Subtract it
ld c,a
ld b,0 ; Expand for 16 bits
jr nc,l3e6d
ld b,-1 ; Signed expansion
l3e6d:
ld hl,(l4450) ; Get current memory pointer
call nz,l3f18
pop bc
ld ix,(l4450) ; Get current memory pointer
ld hl,l7b74 ; Load base
ld b,c ; Copy position
dec b ; Test any
inc b
jr z,l3ea5 ; Nope
l3e80:
ld a,(hl) ; Get character
ld de,(l4464) ; Get start of block pointer
call cmp_hl_de ; Compare HL:DE
jr nz,l3e8e ; Not the same
ld (l4460),ix ; Set block start pointer
l3e8e:
ld de,(l4466) ; Get end of block pointer
call cmp_hl_de ; Compare HL:DE
jr nz,l3e9b ; Not the same
ld (l4462),ix ; Set block end pointer
l3e9b:
ld (ix+0),a ; Unpack character
inc hl
inc ix
djnz l3e80
dec ix
l3ea5:
ld a,cr
ld (ix+0),a ; Set end of line
ret
;
; Display characters left and check enough memory
;
l3eab:
ld hl,(l4548) ; Get top of available memory
or a
sbc hl,de ; Test remainder
jr c,l3ed9 ; Nope
ld bc,l00fe
sbc hl,bc ; Test min
ret nc ; Yeap
add hl,bc
push hl
call l3e0d ; Set cursor
pop hl
ld b,0
call l30fe ; Tell bytes left
call l4211
db ' byte(s) left'
db null
call l3f12 ; Wait for quit
ret
l3ed9:
call l3e04
db 'ERROR: Out of space'
db null
call l3f12 ; Wait for quit
jp l2ebd
;
; Test editor function cancelled
;
l3ef6:
cp a_CAN ; Test cancel
ret nz ; Nope
call l3e04
db '*** INTERRUPTED'
db null
call l3f12 ; Wait for quit
jp l2ebd
;
; Clear ahaed buffer and wait for user quit
;
l3f12:
call l422b ; Clear look ahead buffer
jp l2e76 ; Get ESCape
;
;
;
l3f18:
push hl
push bc
jr nc,l3f96
ld de,(l4546) ; Get end of text
push de
push de
ex de,hl
or a
sbc hl,de
ex (sp),hl
or a
sbc hl,bc
jp nc,l3ed9
ld e,l
ld d,h
push de
call l3eab ; Test enough room
pop de
pop bc
inc bc
pop hl
ld (l4546),de ; Set end of text
ld a,b
l3f3c:
sub HIGH _SavLen
jr c,l3f4d
ld b,a
push bc
ld bc,_SavLen
lddr ; move down
pop bc
call l4232 ; Poll character from input
jr l3f3c
l3f4d:
ld a,c
or b
jr z,l3f53
lddr
l3f53:
pop bc
pop hl
ex de,hl
inc de
ld hl,(l4460) ; Get block start pointer
call l3f8e
ld (l4460),hl ; Set block start pointer
ld hl,(l4462) ; Get block end pointer
call l3f8e
ld (l4462),hl ; Set block end pointer
ld hl,(curstartofpage) ; Get start of screen
call l3f8e
ld (curstartofpage),hl ; Set start of screen
ld hl,(l4450) ; Get current memory pointer
call l3f8e
ld (l4450),hl ; Set current memory pointer
ld hl,(l4454) ; Get block pointer
call l3f8e
ld (l4454),hl ; Set block pointer
ld hl,(l4458) ; Get edit pointer
call l3f8e
ld (l4458),hl ; Set edit pointer
ret
;
;
;
l3f8e:
call cmp_hl_de ; Compare HL:DE
ret c
or a
sbc hl,bc
ret
;
;
;
l3f96:
push hl
add hl,bc
push hl
ld de,(l4546) ; Get end of text
inc de
ex de,hl
or a
sbc hl,de
ld c,l
ld b,h
pop hl
pop de
ld a,b
l3fa7:
sub HIGH _SavLen
jr c,l3fb8
ld b,a
push bc
ld bc,_SavLen
ldir ; move up
pop bc
call l4232 ; Poll character from input
jr l3fa7
l3fb8:
ld a,c
or b
jr z,l3fbf
ldir
dec de
l3fbf:
ld (l4546),de ; Set end of text
jr l3f53
;
;
;
l3fc5:
push hl
ld de,(l4464) ; Get start of block pointer
call l4191 ; Find min
bit 0,(iy+1) ; Test start block
jr z,l3fd6 ; Nope
ld (l4464),hl ; Set start of block pointer
l3fd6:
pop hl
bit 1,(iy+1) ; Test end block
ret z ; Nope
ld de,(l4466) ; Get end of block pointer
call l4191 ; Find min
ld (l4466),hl ; Set end of block pointer
ret
;
;
;set column?
l3fe7:
ld de,l7b74 ; Get base address
ld a,(l0168) ; Get screen columns
dec a
ld c,a
or a
sbc hl,de
ld a,l
sub (iy+0)
jr c,l4012
cp c
jr c,l400e
sub c
inc a
add a,(iy+0)
ld (l446c),a ;xscroll???
ld a,(l0168) ; Get screen columns
dec a
dec a
ld (l4470),a ; Set column to end
jp l3762
l400e:
ld (l4470),a ; Set column
ret
l4012:
add a,(iy+0)
ld (l446c),a ;xscroll???
ld (iy+4),0 ; Clear column
jp l3762
;
;
;
l401f:
bit 0,(iy+7)
ret z
ld hl,(curstartofpage) ; Get start of screen
ld de,(l4544) ; Get start of text
call l4191 ; Find min
ex de,hl
ld (curstartofpage),hl ; Set max for start of screen
ld bc,1
ld de,(l4450) ; Get current memory pointer
call cmp_hl_de ; Compare HL:DE
jp z,l40da ; Same
jr c,l4086 ; HL < Current_Pointer
l4041:
ld de,(l4450) ; Get current memory pointer
call cmp_hl_de ; Compare HL:DE
jr z,l4055 ; Same
call findprevline ; Find previous line
inc bc
ld a,c
or a
call z,l4232 ; Poll character from input
jr l4041
l4055:
ld (curstartofpage),hl ; Set start of screen
ld (iy+5),1 ; Init row
set 0,(iy+14)
ld a,b
or a
jr nz,l4083 ; Test row
ld a,(l01ae) ; Test insert line implemented
or a
jr z,l4083 ; Nope
ld a,(l0169) ; Get screen lines
dec a
cp c
jr c,l4083
dec c
ld hl,256*0+1
call l02a2 ; Position cursor
dec c
push af
inc c
l407b:
call l0262 ; Insert line
dec c
jr nz,l407b
pop af
ret z
l4083:
jp l4147 ; Reset row
l4086:
ld de,(l4450) ; Get current memory pointer
call cmp_hl_de ; Compare HL:DE
jr z,l409a ; Same
call findnexteol ; Find next end of line
inc bc
ld a,c
or a
call z,l4232 ; Poll character from input
jr l4086
l409a:
ld a,b
or a
jr nz,l40de
ld a,(l0169) ; Get screen lines
dec a
ld e,a
ld a,c
sub e
ld d,a
inc d
jr c,l40da
dec d
jr nz,l40b3
bit 0,(iy+21)
jp nz,l4103
l40b3:
inc d
sub e
jr nc,l40de
ld a,(l4475) ; Get current row
sub d ; Test row
jr c,l40de
jr z,l40de
ld (l4475),a ; Set row
ld hl,(curstartofpage) ; Get start of screen
ld b,d
push de
l40c7:
call findnexteol ; Find next end of line
push hl
call l3d0b ; Delete current line
pop hl
djnz l40c7
ld (curstartofpage),hl ; Set start of screen
pop de
l40d5:
dec e
ld (iy+5),e ; Set row
ret
l40da:
ld (iy+5),c ; Set row
ret
l40de:
ld hl,(curstartofpage) ; Get start of screen
dec bc
ld a,(l0169) ; Get screen lines
sub 3
ld e,a
ld a,c
sub e
ld c,a
jr nc,l40ee
dec b
l40ee:
call findnexteol ; Find next end of line
dec bc
ld a,c
or b
jr nz,l40ee
ld (curstartofpage),hl ; Set start of screen
call l4147 ; Reset row
set 0,(iy+14)
jp l401f
l4103:
call l40d5
ld a,(l4475) ; Get current row
ld l,a
ld a,(l0169) ; Get screen lines
cp l
ld a,l
jr z,l4117
dec a
jr z,l4117
ld (l4475),a ; Set row
l4117:
ld hl,(curstartofpage) ; Get start of screen
call findnexteol ; Find next end of line
ld (curstartofpage),hl ; Set start of screen
call l3d0b ; Delete current line
ld a,(l0169) ; Get screen lines
dec a
jp l3bbc
;
; Find delimiter
; ENTRY Reg HL points to current text
; EXIT Carry set if delimiter found
;
l412a:
ld de,(l7b72) ; Get pointer to delimiters
l412e:
ld a,(de) ; Test end of list
or a
ret z ; Yeap
cp (hl) ; Compare
jr z,l4137 ; Got it
inc de
jr l412e
l4137:
scf
ret
;
; Delete line if no ESC sequence present
;
l4139:
push af
ld a,(l4471) ; Get row
cp (iy+9) ; Compare
jr nc,l4145
ld (l4475),a ; Set row
l4145:
pop af
ret
;
; Reset row
;
l4147:
ld (iy+9),1 ; Init row
ret
;
; Adjust pointer for inserting characters
; ENTRY Reg BC holds number of characters to be inserted
;
l414c:
ex de,hl
bit 0,(iy+1) ; Test start block
jr z,l415f ; Nope
ld hl,(l4464) ; Get start of block pointer
call cmp_hl_de ; Compare HL:DE
jr c,l415f ; Start_of_block < DE
add hl,bc ; Add offset
ld (l4464),hl ; Set start of block pointer
l415f:
bit 1,(iy+1) ; Test end block
jr z,l4171 ; Nope
ld hl,(l4466) ; Get end of block pointer
call cmp_hl_de ; Compare HL:DE
jr c,l4171 ; End_of_block < DE
add hl,bc ; Add offset
ld (l4466),hl ; Set end of block pointer
l4171:
ex de,hl
ret
;
;
;
l4173:
push hl
ld bc,-1
call l414c ; Delete one character
ex de,hl
ld hl,l7b74+_LinLen-1
or a
sbc hl,de
jr z,l418a ; Same
ld c,l
ld b,h
ld l,e
ld h,d
inc hl
ldir ; Unpack
l418a:
ld hl,l7b74+_LinLen-1
ld (hl),' ' ; Clear last entry
pop hl
ret
;
; Get minimum of two addresses
; ENTRY Reg HL holds 1st address
; Reg DE holds 2nd address
; EXIT Regs swapped if 1st >= 2nd
;
l4191:
call cmp_hl_de ; Compare HL:DE
ret c ; HL < DE
ex de,hl ; Swap
ret
;
;
;
l4197:
call l37a4 ; Set edit cursor
ld a,(l0168) ; Get screen columns
dec a
sub (iy+4) ; Subtract from column
ld hl,(l4452) ; Get current edit pointer
ld b,a
set 0,(iy+16)
call l3c41
res 0,(iy+16)
ret
;
; Adjust for next end of line
; ENTRY Reg HL holds current pointer
; EXIT Reg HL holds pointer to next line
; Carry set if pointer behind end address
;
findnexteol:
push bc
ex de,hl
ld hl,(l4546) ; Get end of text
dec hl
or a
sbc hl,de ; Build difference
ld b,h
ld c,l
inc bc
ex de,hl
ld d,h
ld e,l
jr c,l41cc ; Out of text
ld a,lf
cpir ; Find new line
jp po,l41cc
or a
pop bc
ret
l41cc:
scf ; Set out of text
ex de,hl
pop bc
ret
;
; Adjust for previous end of line
; ENTRY Reg HL holds current pointer
; EXIT Reg HL holds pointer to previous line
; Carry set if pointer below start address
;
findprevline:
push bc
ld c,l ; Save pointer
ld b,h
ld a,lf
call l3bee ; Fix to start of line
jr c,l41e7 ; Below
l41da:
call l3bee ; Fix to start of line
jr z,l41e5 ; Got start
jr c,l41e7 ; It's below start
cp (hl) ; Find line feed
jr nz,l41da ; Nope
inc hl
l41e5:
pop bc
ret
l41e7:
ld h,b ; Restore pointer
ld l,c
pop bc
ret
;
; Adjust pointer for inserting one character
;
l41eb:
push hl
ld bc,1
call l414c ; Adjust pointer for inserting one character
ld de,l7b74+_LinLen-1
ex de,hl
or a
sbc hl,de ; Get difference
dec hl
ld c,l
ld b,h
ld de,l7b74+_LinLen-2
ld l,e
ld h,d
dec hl
ld a,c
or b ; Test any
jr z,l420c ; Nope
push de
lddr ; move characters
pop hl
ld (hl),' ' ; Clear character
l420c:
pop hl
ret
;
; Position cursor and give immediate string
; ENTRY Reg H holds column
; Reg L holds row
;
l420e:
call l02a2 ; Position cursor
l4211:
jp l01fa ; Give string
;
; #####################################################
; >>> Redirected console output during edit session <<<
; #####################################################
;
l4214:
pop hl
ex (sp),hl
bit 0,(iy+7)
jr z,l4220
push hl
l421e equ $+1
call a_DUMMY ; *** REDIRECTED ***
l4220:
ld a,(l4543)
sub 2
ld (l4543),a
ret nz
jr l423e ; Poll character from input
;
; Clear look ahead buffer
;
l422b:
ld hl,(l445c) ; Get input queue pointer
ld (l445e),hl ; Set for output queue pointer
ret
;
; Poll character from input
;
l4232:
push af
push bc
push de
push hl
call l423e ; Poll character from input
pop hl
pop de
pop bc
pop af
ret
;
; Poll character from input without register preserving
;
l423e:
ld hl,(l445e) ; Get output queue pointer
call l4263 ; Bump it
ld de,(l445c) ; Get input queue pointer
ex de,hl
sbc hl,de ; Test room in output queue
ex de,hl
ret z ; Nope
push hl
push ix
push iy
YIELD
if TERM
GETKEY_ ;call l00a0 ; Test key pressed
else
GET_KEY ;call l00a0 ; Test key pressed
endif
pop iy
pop ix
pop hl
or a
ret z ; No character available
;call readfromkbd ; Read character
ld (hl),a ; Store it
ld (l445e),hl ; Set output queue pointer
ret
;
; Bump and check ahead pointer
; ENTRY Reg HL holds current pointer
; EXIT Reg HL holds position within the queue
;
l4263:
inc hl ; Bump pointer
ld de,l7b59+_Ahead
or a
ex de,hl
sbc hl,de ; Test end of queue
ex de,hl
ret nz ; Nope
ld hl,l7b59 ; Set start of queue
ret
;
; Get character from console or ahead buffer
;
l4271:
push hl
push de
ld de,(l445c) ; Get input queue pointer
ld hl,(l445e) ; Get output queue pointer
or a
sbc hl,de ; Test any in buffer
ex de,hl
jr z,l4289 ; Nope, buffer is empty
call l4263 ; Bump queue pointer
ld a,(hl) ; Get character
ld (l445c),hl ; Set input queue pointer
jr l428c
l4289:
call readfromkbd ; Read character
l428c:
pop de
pop hl
ret
;
; Test look ahead buffer empty - Z set says yes
;
l428f:
push hl
push de
ld de,(l445c) ; Get input queue pointer
ld hl,(l445e) ; Get output queue pointer
or a
sbc hl,de
pop de
pop hl
ret
;
l429e:
dw l7bf5 ; Base of message file
l42a0:
db eof
if 1==0
;default key codes
l42a1::
; Basic movement
db 1,0dh
db 1,1
db 1,0ffh
db 1,6
db 1,0fah
db 1,0fbh
db 1,1fh
db 1,1eh
db 1,0f5h
db 1,0f4h
db 1,0f8h
db 1,0f9h
; Extended movement
db 1,0f6h
db 1,0f7h
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
; Insert and delete commands
db 1,0e0h
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
; Block commands
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
; More commands
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
db 1,0ffh
;
db 0,0ffh
db 1,0ffh
;
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0
endif
l4369::
;
; Basic movement
;
db 1,'M'-'@'
db 1,key_left;'S'-'@'
db 1,key_left;'H'-'@'
db 1,key_right;'D'-'@'
db 1,'A'-'@'
db 1,'F'-'@'
db 1,key_up;'E'-'@'
db 1,key_down;'X'-'@'
db 1,'W'-'@'
db 1,'Z'-'@'
db 1,key_pgup;'R'-'@' ;pgup
db 1,key_pgdown;'C'-'@' ;pgdn
;
; Extended movement
;
db 1,key_home;2,'Q'-'@','S'-'@' ; LINE LEFT (home)
db 1,key_end;2,'Q'-'@','D'-'@' ; LINE RIGHT (end)
db 2,'Q'-'@','E'-'@' ; BOTTOM OF SCREEN
db 2,'Q'-'@','X'-'@' ; TOP OF SCREEN
db 2,'Q'-'@','R'-'@' ; BEGIN OF TEXT
db 2,'Q'-'@','C'-'@' ; END OF TEXT
db 2,'Q'-'@','B'-'@' ;to begin of block
db 2,'Q'-'@','K'-'@' ;to end of block
db 2,'Q'-'@','P'-'@' ;last cursor position
;
; Insert and delete commands
;
db 1,key_ins;'V'-'@' ;insert mode on/off
db 1,'N'-'@' ;insert line
db 1,'Y'-'@' ;delete line
db 2,'Q'-'@','Y'-'@' ;delete to end of line
db 1,'T'-'@' ;delete right word
db 1,key_del;'G'-'@'
db 1,key_backspace;DEL
db 1,key_backspace;0ffh
;
; Block commands
;
db 2,'K'-'@','B'-'@'
db 2,'K'-'@','K'-'@'
db 2,'K'-'@','T'-'@'
db 2,'K'-'@','H'-'@'
db 2,'K'-'@','C'-'@'
db 2,'K'-'@','V'-'@'
db 2,'K'-'@','Y'-'@'
db 2,'K'-'@','R'-'@'
db 2,'K'-'@','W'-'@'
;
; More commands
;
db 1,key_esc;db 2,'K'-'@','D'-'@'
db 1,'I'-'@'
db 2,'Q'-'@','I'-'@'
db 2,'Q'-'@','L'-'@'
db 2,'Q'-'@','F'-'@'
db 2,'Q'-'@','A'-'@'
db 1,'L'-'@'
db 1,'P'-'@'
db 0
l43de::
db '<>,[].*+-/$:=(){}^#'''
l43f2::
db ' ',null
l43f4::
;
; Basic movement
;
dw l38e6 ; NEW LINE
dw l3984 ; CURSOR LEFT
dw l3984 ; CURSOR LEFT
dw l3991 ; CURSOR RIGHT
dw l39ea ; WORD LEFT
dw l3a0b ; WORD RIGHT
dw l37d2 ; LINE UP
dw l37ad ; LINE DOWN
dw l37e0 ; SCROLL UP
dw l3822 ; SCROLL DOWN
dw l389c ; PAGE UP
dw l3872 ; PAGE DOWN
;
; Extended movement
;
dw l3771 ; LINE LEFT (home)
dw l377a ; LINE RIGHT (end)
dw l384d ; BOTTOM OF SCREEN
dw l385f ; TOP OF SCREEN
dw l38bc ; BEGIN OF TEXT
dw l3768 ; END OF TEXT
dw l373c ; BEGIN OF BLOCK
dw l3745 ; END OF BLOCK
dw l399a ; LAST CURSOR POSITION
;
; Insert and delete commands
;
dw l378f ; TOGGLE INSERT/OVERWRITE
dw MMSB+l393b ; INSERT LINE
dw MMSB+l3aec ; DELETE LINE
dw MMSB+l3ad2 ; DELETE TO END OF LINE
dw MMSB+l3b42 ; DELETE RIGHT WORD
dw MMSB+l3b73 ; DELETE RIGHT CHARACTER
dw MMSB+l3b78 ; DELETE LEFT CHARACTER
dw MMSB+l3b78 ; DELETE LEFT CHARACTER
;
; Block commands
;
dw l3726 ; MARK BEGIN OF BLOCK
dw l3702 ; MARK END OF BLOCK
dw l39ac ; MARK SINGLE WORD
dw l36f9 ; TOGGLE BLOCK DISPLAY
dw MMSB+l3620 ; COPY BLOCK
dw MMSB+l35fb ; MOVE BLOCK
dw MMSB+l36a1 ; DELETE BLOCK
dw MMSB+l3573 ; READ BLOCK FROM FILE
dw l34ed ; WRITE BLOCK TO FILE
;
; More commands
;
dw l2b0f ; EXIT EDITOR
dw MMSB+l3a72 ; TABULATE
dw l379b ; TOGGLE TABULATE
dw MMSB+l3d2c ; RESTORE DELETED LINE
dw l31f1 ; FIND STRING
dw l323b ; FIND AND REPLACE STRING
dw l324b ; REPEAT LAST SEARCH
dw MMSB+l2f02 ; CONTROL PREFIX
l4450::
dw 0 ; Current memory pointer
l4452:
dw l7b74 ; Current edit pointer
l4454:
dw 0 ; Block pointer
l4456:
dw l7b74
l4458:
dw 0 ; Edit pointer
l445a:
dw l7b74
l445c:
dw l7b59 ; Input queue pointer
l445e:
dw l7b59 ; Output queue pointer
l4460:
dw 0 ; Block start pointer
l4462:
dw 0 ; Block end pointer
l4464:
dw 2 ; Block start pointer
l4466:
dw 2 ; Block end pointer
l4468:
dw 0 ; Temporry edit pointer
curstartofpage:
dw 0 ; Start of screen
;
; The editor status block
;
l446c:
db 0 ; + 0 xscroll???
db 0 ; + 1: Block state
; xxxxxxx1: Start set)
; xxxxxx1x: End set)
db 1 ; + 2
l446f:
db 1 ; + 3: Relative column
l4470:
db 0 ; + 4: Editor column
l4471:
db 1 ; + 5: Editor row
l4472:
db 0 ; + 6: Insert flag (Bit 0=0)
db 1 ; + 7: Video flag (1 is reverse)
l4474:
db 0 ; + 8: Change flag
l4475:
db 1 ; + 9: Editor row
l4476:
db 0 ; +10
db 0 ; +11
l4478:
db 0 ; +12
l4479:
db 0 ; +13: Auto tabulate flag
db 1 ; +14
db 1 ; +15
db 0 ; +16
l447d:
db 0 ; +17: Option flags for search/replace
; 00000001: W: Whole word search
; 00000010: N: No request
; 00000100: U: Ignore case
; 00001000: G: Global search
; 00010000: B: Backwards
l447e:
db 0 ; +18: Find (0) or replace (-1) flag
l447f:
db 0 ; +19: Text change flag
l4480:
db 0 ; +20: Block marker (1: Not set)
db 0 ; +21
l4482:
db 3 ; +22
l4483:
db 0,0,0
l4486:
db 0,0
l4488:
dw 0 ; End of search pointer
l448a:
dw 0 ; Search loop count
l448c:
dw 0
l448e:
dw 0
;
; Search buffer
;
l4490:
db 1eh
l4491:
db 0
l4492:
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0
;
; Replace buffer
;
l44b1:
db 1eh
l44b2:
db 0
l44b3:
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 0,0,0
;
; Option buffer
;
l44d2:
db 0ah
db 0,0,0,0,0,0,0,0,0,0,0,0
;
; Block file name
;
l44df:
db 0fh
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
l44f1:
db 0 ; File flag
l44f2:
db 0 ; Rename flag (1 is rename)
l44f3:
db 1 ; Compile flag:
; 1: Compile to memory
; 2: Compile to COM-file
; 3: Compile to CHN-file
l44f4:
dw l20e2 ; Start address of compiler
l44f6:
dw 0 ; Top of available memory
l44f8:
db 0 ; Logged disk
l44f9:
ds FCBlen ; Main file
l451d:
ds FCBlen
l4541:
db 0 ; Error message file flag (0 is not read)
l4542:
db 0 ; Compile flag
l4543:
db 0
l4544:
dw l7bf5 ; Start of text
l4546:
dw l7bf5 ; End of text
l4548:
dw 0 ; Top of available memory
;
; %%%%%%%%%%%%%%%%%%%%%%
; %%% COMPILER ENTRY %%%
; %%%%%%%%%%%%%%%%%%%%%%
;
COMPILE:
ld (l7b71),sp ; Save stack
ld hl,(l4546) ; Get end of text
inc hl
ld (MemsTop),hl ; Save for memory top
inc h ; Allow a gap of 1024 bytes
inc h
inc h
inc h
ld (COMsTop),hl ; Save for top of .COM file
ld hl,(l790a) ; Get end of code
ld (DataBeg),hl ; Save for start of data
xor a
ld h,a
ld l,a
ld (l7b91),a ; Clear ????
ld (l7b92),a ; Clear ????
ld (l7b94),a ; Clear ????
ld (l7ba2),a ; Clear end of file
ld (l7ba0),a ; Clear end on break [option U+]
ld (BackLevel),a ; Clear back fix level
ld (IncFlg),a ; Enable memory read
ld (l7b96),a ; Clear OVERLAY number
ld (RRN_stat ),a ; Clear file access
ld (RRN_off),hl ; Clear record base
ld (l7bef),hl ; Clear line count
call l718f ; Test abort
dec hl
ld (FFCB+_rrn),hl ; Set highest record
ld a,_Char+1 ;13=element of a set???
ld (curtype_l7b93),a ; Set special type
ld a,0xff-(__Ropt+__Uopt)
ld (l7b9d),a ; Set default options
ld a,2*DefWITH
ld (l7bc7),a ; Set depth for WITH
ld hl,(l4544) ; Get start of text
ld (l7bd7),hl ; Init source pointer
ld (l7bd9),hl
ld ix,l79d7 ; Init start of line
ld (ix+0),null ; Set line empty
ld hl,(l7904) ; Get code start address
call ChkChn ; Check chaining
ld hl,(l4548) ; Get top of available memory
dec hl
ld (l7b77),hl ; Save
ld d,h
ld e,l
ld bc,LenLab ; Get length of internal table
or a
sbc hl,bc
ld (LabPtr),hl ; Init label pointers
ld (PrevLabPtr),hl
ld (CurLab),hl
call ChkOvfl ; Check enough memory
ld hl,l731f+LenLab-1
lddr ; Unpack symbol table
call l45ea ; Go compile
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr nz,l45e2 ; Nope
call FixBack ; Fix back level
call writerecord_TmpBuff ; Write record
ld c,_close
ld de,FFCB
call _BDOS ; must close output file!!!
l45e2:
ld (l7906),iy ; Save new top of code
xor a
jp l72e3 ; Set special zero error
;
; Do the compiler task
;
l45ea:
call GetLine ; Process line
call FindStr ; Find PROGRAM
dw l7529
jr nz,l460a ; Nope
call l4692 ; Build dummy label
call l6f1b ; Test (
jr nz,l4607 ; Nope
l45fc:
call l4692 ; Build dummy label
call l6f13 ; Test ,
jr z,l45fc ; Yeap, get next dummy
call l6f6e ; Verify )
l4607:
call l6f48 ; Verify ;
l460a:
ld a,_LD.SP
ld hl,0x0100;TPA
call StCode ; Set LD SP,TPA
ld hl,l79d7 ; Get start of source line
ld a,(CmpTyp) ; Get compile flag
or a ; Test compile to memory
jr z,l4621 ; Yeap
ld de,l0080
call VarAlloc ; Allow space for loader
l4621:
call StLD.HL ; Set LD HL,L79D7
ld a,(l7b9d) ; Get options
bit _Copt,a ; Test $C+
ld d,0
jr z,l462e ; Nope
dec d
l462e:
push de ; Save flag
ld a,_LD.BC
call writebyte_a_addriy ; Set LD BC,FLAG
push iy ; Save PC
call writeword_hl_addriy ; Set dummy word
ld hl,l0364
call StCALL_ ; Set CALL INIPRG
ld a,_LD.HL
call writebyte_a_addriy ; Set LD HL,1STFREE
push iy ; Save PC
call writeword_hl_addriy ; Set dummy word
ld a,_LD.DE
call writebyte_a_addriy ; Set LD DE,LASTFREE
push iy ; Save PC
call writeword_hl_addriy ; Set dummy word
ld hl,(l790a) ; Get end of code
call StLD.BC ; Set LD BC,TOPRAM
ld a,(CmpTyp) ; Get compile flag
ld h,a
ld l,_LD.A
call writeword_hl_addriy ; Set LD A,FLAG
ld hl,l04d4
call StCALL_ ; Set CALL RANGCHK
call l469e ; Do a block
call l52fc
ld a,(ix+0)
cp '.' ; Verify closing .
call ErrNZ
db _DotExp
ld hl,l20d4
call StJP_ ; Set JP HALT
pop hl ; Get back PC for LASTFREE
ld de,(DataBeg) ; Get start of data
call storeback_de_to_addrhl ; Store back
pop hl ; Get back PC for 1STFREE
call storeback_iy_to_addrhl ; Store back current PC
pop hl ; Get back PC for FLAG
pop de ; Get FLAG
ld a,(l7ba0) ; Get end on break flag [option U+]
ld e,a
jp storeback_de_to_addrhl ; Store it back
;
; Build dummy label
;
l4692:
ld hl,(LabPtr) ; Get label pointer
push hl ; Save it
call GetLabel ; Get label
pop hl
ld (LabPtr),hl ; Restore label pointer
ret
;
; Perform a block
;
l469e:
ld a,(l7bc7) ; Get depth for WITH
push af
add a,a ; Double it
ld e,a
ld d,0
call VarAlloc ; Allocate space for it
push hl
call StJP ; Set JP
push iy ; Save PC
push hl
call writeword_hl_addriy ; Set dummy word
l46b3:
call FndTabStr ; Find statement
db _Byte
dw l7584
call ErrNZ ; Must be
db _BEGINexp
ld a,(hl) ; Get type
l46be:
cp _Label ; Test LABEL
jr nz,l46c7 ; Nope
call l488e ; Process it
jr l46b3
l46c7:
cp _Const ; Test CONST
jr nz,l46d0 ; Nope
call l48b7 ; Process it
jr l46be
l46d0:
cp _Type ; Test TYPE
jr nz,l46d9 ; Nope
call l4aeb ; Process it
jr l46be
l46d9:
cp _Var ; Test VAR
jr nz,l46e6 ; Nope
call l4b2a ; Process it
ld hl,(DataBeg) ; Get start of data
ex (sp),hl
jr l46be
l46e6:
cp _Overly ; Test OVERLAY
jp nz,l485e
ld a,(CmpTyp) ; Get compile flag
or a
call ErrZ ; Must not be compiled to memory
db _OvlDirErr
ld hl,FFCB+Fdrv
ld de,l7bb2
ld bc,Fname
ldir ; Copy name of file
ld hl,l7b96 ; Point to OVERLAY number
ld a,(hl) ; Get current number
inc (hl) ; Advance it
ex de,hl ; Get pointer to extension
ld (hl),'0' ; Init extension
inc hl
ld b,'0'-1 ; Init tens
l4709:
inc b ; Divide by ten
sub 10
jr nc,l4709
ld (hl),b ; Save tens
inc hl
add a,'9'+1 ; Calculate units
ld (hl),a ; Save it
ld hl,l1c59
call StCALL_ ; Set CALL OVERLAY
ld hl,-1
call writeword_hl_addriy ; Save word
ld hl,l7bb2 ; Point to name
ld b,Fname+Fext
l4724:
ld a,(hl)
call writebyte_a_addriy ; Store name and extension
inc hl
djnz l4724
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr nz,l473b ; Nope
call FixBack ; Fix back level
xor a
ld (BackLevel),a ; Set back fix level
call writerecord_TmpBuff ; Write record
l473b:
ld hl,(RRN_off) ; Get record base
push hl
ld hl,(CodePC) ; Get code pointer
push hl
ld hl,(l7bb0) ; Get length of overlay
push hl
ld (CodePC),iy ; Set code pointer
ld hl,0
ld (l7bb0),hl ; Clear length of overlay
ld hl,-FCBlen
add hl,sp ; Let some space on stack for FCB
ld sp,hl
ex de,hl
ld hl,FFCB
ld bc,FCBlen
ldir ; Unpack current FCB
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr nz,l478c ; Nope
ld hl,l7bb2
ld de,FFCB+Fdrv
ld bc,Fname+Fext
ldir ; Copy overlay FCB to .COM FCB
ex de,hl
ld b,FCBlen-Fdrv-Fname-Fext
l4773:
ld (hl),0 ; Clear remainder of FCB
inc hl
djnz l4773
ld de,FFCB
push de
ld c,_delete
call _BDOS ; Delete file
pop de
ld c,_make
call _BDOS ; Create new one
inc a
call ErrZ ; Must be success
db _NoOvl
l478c:
xor a
ld (RRN_stat ),a ; Clear file access
ld (RecPtr),a ; Clear record pointer
ld hl,(DataBeg) ; Get start of data
ld (l7bab),hl ; Set for overlay
l4799:
call FndTabStr ; Find PROCEDURE or FUNCTION
db 1
dw l75a7
call ErrNZ ; Must be either
db _SUBexp
ld a,(hl) ; Get type
push iy
ld hl,(FFCB+_rrn) ; Get current record
ld (RRN_off),hl ; Set record base
ld hl,(DataBeg) ; Get start of data
push hl
ld hl,(l7bab) ; Get address of overlay data
push hl
ld e,-1
call l4b3a ; Perform PROCEDURE/FUNCTION
ld b,h
ld c,l
pop de ; Get back overlay data
ld hl,(DataBeg) ; Get start of data
or a
sbc hl,de ; Test min
add hl,de
jr c,l47c6
ex de,hl ; Swap addresses
l47c6:
ld (l7bab),hl ; Set address of overlay data
pop hl
ld (DataBeg),hl ; Set start of data
pop de
push bc
push de
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
call z,FixBack ; Yeap, fix back level
xor a
ld (BackLevel),a ; Reset back fix level
pop de
push de
l47dd:
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to memory
call z,flushunfinished ;nope
push iy ; Copy code pointer
pop hl
or a
sbc hl,de ; Get difference
ld a,l
and RecLng-1 ; Test record boundary
jr z,l47ee ; Yeap
xor a
call writebyte_a_addriy ; Fill remainder with zeroes
jr l47dd
l47ee:
add hl,hl ; Calculate lenght in bytes
ld e,h
ld d,0
rl d
ld hl,(l7bb0) ; Get length of overlay
sbc hl,de ; Test max
jr nc,l47ff
ld (l7bb0),de ; Set new length
l47ff:
pop iy ; Get back PC
pop hl
inc hl
ld (hl),e ; Save record
inc hl
ld (hl),d
call FindStr ; Find more OVERLAY
dw l759f
jr z,l4799 ; Yeap
ld hl,(l7bab) ; Get address of overlay data
ld (DataBeg),hl ; Set start of data
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr nz,l4821 ; Nope
ld de,FFCB
ld c,_close
call _BDOS ; Close file
l4821:
ld hl,0
add hl,sp ; Copy stack
ld de,FFCB
ld bc,FCBlen
ldir ; Get back original .COM FCB
ld sp,hl
ld de,(l7bb0) ; Get length of overlay
pop hl
ld (l7bb0),hl ; Set new length
pop hl
ld (CodePC),hl ; Set code pointer
pop hl
ld (RRN_off),hl ; Set record base
xor a
ld (RRN_stat ),a ; Clear file access
ld hl,-1
ld (FFCB+_rrn),hl ; Set highest record number
push iy
pop hl
call ChkChn ; Check chaining
l484e:
ld b,RecLng
l4850:
xor a
call writebyte_a_addriy ; Clear record
djnz l4850
dec de
ld a,d ; Test all done
or e
jr nz,l484e
jp l46b3
l485e:
cp _Begin ; Test BEGIN
jr z,l486a ; Yeap
ld e,0
call l4b3a ; Perform PROCEDURE/FUNCTION
jp l46b3
l486a:
call l4e8a ; Process it
pop de
pop hl
push de
push iy ; Copy PC
pop de
dec de ; Fix it
dec de
or a
sbc hl,de ; Calculate size
add hl,de
jr z,l4880
call storeback_iy_to_addrhl ; Store back PC
jr l4884
l4880:
dec hl
call ChkChn ; Check chaining
l4884:
pop de
pop hl
ld (l7bca),hl
pop af
ld (l7bc6),a
ret
;
; Process LABEL
;
l488e:
ld de,256*1+0
call puttolabel_d_e ; Put to table
ld a,(ix+0)
call IsItValid ; Test valid character
call SampLabel ; Build label
ld a,(l7b94) ; Get ???
call puttolabel ; Put to label
ld b,3
l48a5:
ld a,-1
call puttolabel ; Set end
djnz l48a5
call SetLabPtr ; Set label pointer
call l6f13 ; Test ,
jr z,l488e ; Yeap
jp l6f48 ; Verify ;
;
; Process CONST
;
l48b7:
ld hl,(LabPtr) ; Get label pointer
push hl
ld de,256*0+0
call puttolabel_d_e ; Put to table
call GetLabel ; Get label
call l6f23 ; Test =
jr nz,l4901 ; Nope, must be : then
call GetConst ; Get constant
ld a,b ; Get type
call puttolabel ; Store into table
ld a,b ; Get back type
cp _Real ; Test real
jr nz,l48e3 ; Nope
exx
push hl ; Save reals
push de
push bc
ld b,3 ; Set word count
l48db:
pop de ; Get part of real
call puttolabel_d_e ; Put to table
djnz l48db
jr l48fa
l48e3:
cp _String ; Test string
jr nz,l48f6 ; Nope, must be integer
ld hl,l7a57 ; Get buffer
ld a,c ; Get length
inc c ; Fix it
l48ec:
call puttolabel ; Put to table
ld a,(hl)
inc hl
dec c
jr nz,l48ec
jr l48fa
l48f6:
ex de,hl ; Get integer
call puttolabel_d_e ; Put to table
l48fa:
call SetLabPtr ; Set label pointer
ld d,2
jr l4928
l4901:
call l6f40 ; Verify :
xor a
call puttolabel ; Store zero in table
call puttolabel_i_y ; Store PC to table
ld hl,(LabPtr) ; Get label pointer
push hl
call puttolabel_d_e ; Put to table
call SetLabPtr ; Set label pointer
call l4f9b ; Get type
pop hl ; Get back label pointer
ld de,(l7b5a) ; Get type table
ld (hl),d ; Store into
dec hl
ld (hl),e
call l6f76 ; Verify =
call l4937 ; Assign constant
ld d,4
l4928:
pop hl ; Get back label pointer
ld (hl),d ; Put into
call l6f48 ; Verify ;
call FndTabStr ; Find statement
db 1
dw l7584
jr nz,l48b7 ; Nope
ld a,(hl) ; Get type
ret
;
; Process presetted constant
;
l4937:
ld a,(l7b5c) ; Get type
cp _Ptr ; Test valid
jr c,l4946 ; May not be a file
cp _String
jr nc,l4946
call ERROR
db _InvFilPtr
l4946:
cp _Array ; Test ARRAY constant
jr nz,l49a1 ; Nope
call l6d2a ; Save environment
ld hl,(l7b60) ; Get hi set limit
call l5271 ; Load name
ld hl,(l7b6d) ; Get last memory address
ld de,(l7b6b)
or a
sbc hl,de
inc hl
push hl
ld hl,(l7b5e) ; Get lo set limit
call l5287 ; Get name
pop de
ld a,(l7b5c) ; Get type
cp _Char ; Test character
jr nz,l4978
ld a,d ; Test byte
or a
jr nz,l4978 ; Nope
call l6f1b ; Test (
jr nz,l498a ; Nope
jr l497b
l4978:
call l6f66 ; Verify (
l497b:
push de
call l4937 ; Recursive assign constant
pop de
dec de
ld a,d
or e
jr z,l499a
call l6f5e ; Verify ,
jr l497b
l498a:
push de
call _GetStrC ; Get string constant
pop de
ld a,c ; Get length
cp e
call ErrNZ ; Verify valid length
db _StrConst
call StConst ; Store string
jr l499d
l499a:
call l6f6e ; Verify )
l499d:
call RestEnv1 ; Get back environment
ret
l49a1:
cp _Record ; Test RECORD constant
jr nz,l49fa ; Nope
call l6d2a ; Save environment
call l6f66 ; Verify (
ld a,(l7b5d)
ld c,a
ld hl,(l7b62) ; Get length of type
push hl
ld hl,0
l49b6:
push bc
push hl
ld b,_Ptr
call FndLABEL ; Get pointer label
call ErrNZ ; Should be found
db _Undef
call l5276 ; Get values and name
pop de
ld hl,(l7b58) ; Get value
or a
sbc hl,de
add hl,de
call ErrNZ ; Verify valid size
db _InvSetOrder
ld de,(l7b62) ; Get length of type
add hl,de
push hl
call l6f40 ; Verify :
call l4937 ; Assign constant recursively
pop hl
pop bc
call l6f0f ; Test ;
jr z,l49b6 ; Yeap
call l6f6e ; Verify )
pop de
ex de,hl
or a
sbc hl,de
l49eb:
ld a,h ; Test zero
or l
jr z,l49f6 ; Yeap
xor a
call writebyte_a_addriy ; Fill zeroes
dec hl
jr l49eb
l49f6:
call RestEnv1 ; Get back environment
ret
l49fa:
cp _Set ; Test SET constant
jr nz,l4a7a ; Nope
call l6d2a ; Save environment
ld hl,(l7b62) ; Get length of type
ld (l7b6f),hl
ld hl,(l7b5e) ; Get lo set limit
call l5287 ; Get name
call l6f30 ; Verify [
ld (l7ba9),ix ; Save line pointer
call l0581 ; Initialize a set on stack
ld ix,(l7ba9) ; Get back line pointer
call l6ef7 ; Test ]
jr z,l4a4b ; Yeap
l4a20:
call l4aca
push hl
call FindStr ; Find ..
dw l7580
jr nz,l4a37 ; Nope
call l4aca
ld (l7ba9),ix ; Save source pointer
call l059b ; Init a contiguous set value
jr l4a3f
l4a37:
pop hl
ld (l7ba9),ix ; Save source pointer
call l0591 ; Init one set element
l4a3f:
ld ix,(l7ba9) ; Get back source pointer
call l6f13 ; Test ,
jr z,l4a20 ; Yeap
call l6f38 ; Verify ]
l4a4b:
ld hl,l7a57
ld bc,set.len
ld (l7ba9),ix ; Save source pointer
call l0612 ; Assign set variable
ld ix,(l7ba9) ; Get back source pointer
ld hl,l7a57
ld a,(l7b5e) ; Get lo set limit
rra ; Divide by 8
rra
rra
and set.len-1 ; Get modulo
ld e,a
ld d,0
add hl,de ; Build pointer
ld a,(l7b6f) ; Get length
ld b,a
l4a6f:
ld a,(hl) ; Get bytes
call writebyte_a_addriy ; Store them
inc hl
djnz l4a6f
call RestEnv1 ; Get back environment
ret
l4a7a:
cp _String ; Test STRING constant
jr nz,l4a99 ; Nope
call _GetStrC ; Get string constant
ld a,(l7b62) ; Get length of string
dec a
sub c
ld b,a
jr nc,l4a8d
add a,c
ld c,a ; Set length
ld b,0
l4a8d:
call StLen ; Put string
inc b
l4a91:
dec b
ret z
xor a
call writebyte_a_addriy ; Fill zeroes
jr l4a91
l4a99:
cp _Real ; Test REAL constant
jr nz,l4abc ; Nope
call _GetConst ; Get constant
ld a,b ; Get type
cp _Real ; Test real
jr z,l4aaf ; Yeap
cp _Integ ; Test integer
call ErrNZ ; Should be
db _IntRealCexp
call l1008 ; Convert to real
exx
l4aaf:
exx
push bc
push de
push hl
ld b,Real.Len/2 ; Set word count
l4ab5:
pop hl
call writeword_hl_addriy ; Save real number
djnz l4ab5
ret
l4abc:
call l4aca
ld a,(l7b62) ; Get length of type
dec a
ld a,l
jp z,writebyte_a_addriy ; Set byte
jp writeword_hl_addriy ; Or set word
;
;
;
l4aca:
call _GetConst ; Get constant
ld a,(l7b5c) ; Get type
cp b ; Verify same types
call ErrNZ
db _InvType
ld de,(l7b5e) ; Get lo set limit
call l728d ; Compare
jr c,l4ae7 ; Out of range
ld de,(l7b60) ; Get hi set limit
call l728d ; Compare
ret c
ret z
l4ae7:
call ERROR
db _ConstRange
;
; Process TYPE
;
l4aeb:
ld hl,(LabPtr) ; Get label pointer
push hl
l4aef:
ld hl,(LabPtr) ; Get label pointer
push hl
ld de,0
call puttolabel_d_e ; Put to table
call GetLabel ; Get label
ld hl,(LabPtr) ; Get label pointer
push hl
call puttolabel_d_e ; Put to table
call SetLabPtr ; Set label pointer
call l6f76 ; Verify =
call l4f9b ; Get type
pop hl
ld de,(l7b5a) ; Get type table
ld (hl),d ; Store into
dec hl
ld (hl),e
pop hl
ld (hl),3
call l6f48 ; Verify ;
call FndTabStr ; Find statement
db _Byte
dw l7584
jr nz,l4aef ; Nope
ld a,(hl) ; Fetch type
pop hl
push af
call l5295
pop af
ret
;
; Process VAR
;
l4b2a:
call l4f35
call l6f48 ; Verify ;
call FndTabStr ; Find statement
db _Byte
dw l7584
jr nz,l4b2a ; Nope
ld a,(hl) ; Fetch type
ret
;
; Perform PROCEDURE/FUNCTION
;
; Accu holds PROCEDURE or FUNCTION
; Reg E holds overlay flag (-1)
;
l4b3a:
ld b,a
ld c,0
sub _Proc ; Get type
ld (l7b97),a ; 0 is PROCEDURE
ld a,e ; Get overlay
ld (l7b99),a ; 0 is normal
ld a,(l7b9d) ; Get options
ld (l7b9e),a ; Set local options
push bc
call l6ddb
jp z,l4c61
pop de
call puttolabel_d_e ; Put to table
call GetLabel ; Get label
ld hl,(CurLab) ; Get current label pointer
push hl
ld hl,(PrevLabPtr) ; Get previous label pointer
ld (CurLab),hl
ld hl,(LabPtr) ; Get label pointer
push hl
call puttolabel_d_e ; Put to table
call puttolabel_d_e ; Multiple
call puttolabel_d_e
call puttolabel_d_e
ld de,(RRN_off) ; Get record base
call puttolabel_d_e ; Put to table
ld de,0
call puttolabel_d_e ; Put to table
call l6f1b ; Test (
ld b,0 ; Clear parameter count
jr nz,l4bda ; Nope
l4b88:
push bc
ld hl,(LabPtr) ; Get label pointer
push hl
call puttolabel_d_e ; Put to table
call puttolabel_d_e ; Twice
call FindStr ; Find VAR
dw l7595
ld bc,0
jr nz,l4b9e ; Nope
dec c ; Indicate VAR
l4b9e:
push bc
call GetLabel ; Get label
pop bc
inc b ; Count parameters
call l6f13 ; Test ,
jr z,l4b9e ; Yeap
push bc
call l6f0b ; Test :
jr nz,l4bb8 ; Nope
ld a,c
ld (l7b8f),a ; Save state
call l4f18 ; Get variable
jr l4bc3
l4bb8:
inc c ; Verify not VAR
call ErrNZ
db _SemiExp
ld hl,l750b+7
ld (l7b5a),hl ; Init type table
l4bc3:
pop bc
pop hl
ld (hl),b
dec hl
ld (hl),c
ld de,(l7b5a) ; Get type table
dec hl
ld (hl),d ; Store into
dec hl
ld (hl),e
pop bc
inc b
call l6f0f ; Test ;
jr z,l4b88 ; Yeap
call l6f6e ; Verify )
l4bda:
push bc
ld a,(l7b97)
or a ; Test PROCEDURE
jr z,l4c07 ; Yeap
call l6f40 ; Verify :
xor a
ld (l7b8f),a
call l4f18 ; Get variable
ld a,(l7b5c) ; Get type
cp _String ; Test range
jr nc,l4bf8
cp _Ptr ; Should be pointer
call ErrNZ
db _InvResult
l4bf8:
pop bc
pop hl
push hl
push bc
ld de,-4
add hl,de ; Fix pointer
ld de,(l7b5a) ; Get type table
ld (hl),d ; Store into
dec hl
ld (hl),e
l4c07:
pop bc
pop de
pop hl
ld (CurLab),hl ; Restore current label pointer
push de
push bc
call SetLabPtr ; Set label pointer
call l6f48 ; Verify ;
ld a,(l7b99)
or a ; Test overlay
jr nz,l4c44 ; Yeap
call FindStr ; Find FORWARD
dw l7533
jr nz,l4c2c ; Nope
push iy ; Copy PC
pop de
call StJP_ ; Set JP <addr>
ld a,-1
jr l4c38
l4c2c:
call FindStr ; Find EXTERNAL
dw l753a
jr nz,l4c44 ; Nope
call _GetIntC ; Get integer constant
ex de,hl
xor a
l4c38:
pop bc
pop hl
ld (hl),a ; Store values
dec hl
ld (hl),b
dec hl
ld (hl),d ; Set address
dec hl
ld (hl),e
jp l6f48 ; Verify ;
l4c44:
pop bc
pop hl
push hl
ld (hl),0 ; Set values
dec hl
ld (hl),b
dec hl
push iy ; Copy PC
pop de
ld a,(l7b99)
or a ; Test overlay
jr z,l4c5b ; Nope
ex de,hl
ld bc,-16
add hl,bc ; Fix value
ex de,hl
l4c5b:
ld (hl),d ; Save address
dec hl
ld (hl),e
pop hl
jr l4c76
l4c61:
ld a,(hl)
or a
call ErrZ ; Verify label not found
db _DoubleLab
ld a,(l7b99)
or a ; Test overlay (0 is not)
call ErrNZ ; Verify not FORWARD overlay
db _OvlFORW
call SetLine ; Set new pointer
pop de
call l6f48 ; Verify ;
l4c76:
ex de,hl
ld a,(l7b9d) ; Get option
ld hl,(DataBeg) ; Get start of data
bit _Aopt,a ; Test $A+ - absolute code for recursion
jr z,l4c84 ; Yeap
ld hl,0
l4c84:
ld (l7b83),hl
ld hl,(CurLab) ; Get current label pointer
push hl
ld hl,(LabPtr) ; Get label pointer
ld (CurLab),hl ; Into current
push hl
ex de,hl
ld a,(hl)
ld (hl),0
dec hl
ld b,(hl)
dec hl
ld d,(hl)
dec hl
ld e,(hl)
dec hl
or a
jr z,l4ca7
push hl
ex de,hl
inc hl
call storeback_iy_to_addrhl ; Store back PC
pop hl
l4ca7:
ld a,(l7b97)
or a ; Test PROCEDURE
jr z,l4cd2 ; Yeap
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push hl
ex de,hl
call l5287 ; Get name
ld a,(l7b5c) ; Get type
ld (l7b87),a
ld hl,(l7b62) ; Get length of type
ld a,l
ld (l7b88),a ; save lo
ex de,hl
call VarAlloc ; Allocate space
ld (l7b89),hl
ex de,hl
pop hl
ld (hl),d
dec hl
ld (hl),e
dec hl
jr l4cd6
l4cd2:
ld de,-4
add hl,de
l4cd6:
ld de,-4
add hl,de
push hl
ld c,0
ld a,b
or a
jr z,l4d2b
l4ce1:
ld a,(hl)
add a,c
ld c,a
push bc
ld b,(hl)
dec hl
ld a,(hl)
ld (l7b8f),a
dec hl
ld d,(hl) ; Get type table
dec hl
ld e,(hl)
dec hl
push hl
ex de,hl
ld (l7b5a),hl ; Save type table
call l5287 ; Get name
ld hl,(LabPtr) ; Get label pointer
ex (sp),hl
push bc
l4cfd:
push bc
ld de,4*256+0
call puttolabel_d_e ; Put to table
l4d04:
ld a,(hl)
call puttolabel ; Store into table
bit _MB,(hl) ; Test end of table
dec hl
jr z,l4d04 ; Nope
push hl
call puttolabel ; Store last byte into table
call puttolabel_d_e ; Put to table
call puttolabel_d_e
call SetLabPtr ; Set label pointer
pop hl
pop bc
djnz l4cfd
pop bc
ex (sp),hl
xor a
ld (l7b90),a
call l4f52
pop hl
pop bc
djnz l4ce1
l4d2b:
ld b,c
push bc
ld hl,(LabPtr) ; Get label pointer
push hl
ld hl,(l7b83)
push hl
ld hl,(l7b89)
push hl
ld a,(l7b87)
push af
ld a,(l7b88)
push af
ld a,(l7b97) ; Get PROCEDURE/FUNCTION flag
push af ; Save it
ld hl,l7b94 ; Point to ???
inc (hl)
call l469e ; Perform a block
pop af
ld (l7b97),a ; Reset flag
pop af
ld (l7b88),a
pop af
ld (l7b87),a
pop hl
ld (l7b89),hl
pop hl
ld (l7b83),hl
ld (l7b85),de
ld a,h
or l
jr z,l4d79
sbc hl,de
jr z,l4d79
call StLD.BC ; Set LD BC,val16
ex de,hl
call StLD.HL ; Set LD HL,val16
ld hl,l0508 ; Set recursion routine
call StCALL_ ; Set CALL RECUR
l4d79:
pop hl
pop bc
inc b
dec b
jp z,l4df3
call StImm ; Set POP IY
db a_L1
s_I1:
POP IY
a_L1 equ $-s_I1
l4d86:
push bc
inc hl
ld e,(hl)
inc hl
ld d,(hl)
add hl,de
push hl
dec hl
dec hl
l4d8f:
bit _MB,(hl) ; Test end of string
dec hl
jr z,l4d8f ; Nope
call l5276 ; Get values and name
ld a,(Envir1)
or a
jr nz,l4dd4
ld a,(l7b5c) ; Get type
cp _Set
jr c,l4dbd
jr z,l4de6
cp _Ptr
jr z,l4de3
cp _String
jr c,l4dbd
jr z,l4de6
cp _Integ
jr nc,l4de3
call StImm ; Set POP sequence
db a_L2
s_I2:
POP HL
POP DE
POP BC
a_L2 equ $-s_I2
jr l4de6
l4dbd:
call StPOP ; Set POP HL
ld hl,(l7b58) ; Get value
call StLD.DE ; Set LD DE,val16
ld hl,(l7b62) ; Get length of type
call StLD.BC ; Set LD BC,val16
call StImm ; Set LDIR
db a_L3
s_I3:
LDIR
a_L3 equ $-s_I3
jr l4de9
l4dd4:
xor a
ld (Envir1),a
ld a,_Ptr
ld (l7b5c),a ; Set POINTER
ld hl,2
ld (l7b62),hl ; Set length of pointer type
l4de3:
call StPOP ; Set POP HL
l4de6:
call l661b
l4de9:
pop hl
pop bc
djnz l4d86
call StImm ; Set PUSH IY
db a_L4
s_I4:
PUSH IY
a_L4 equ $-s_I4
l4df3:
call l52fc
ld hl,l7b94 ; Point to ???
dec (hl)
ld a,(l7b97)
or a ; Test PROCEDURE
jr z,l4e46 ; Yeap
ld hl,(l7b89)
ld a,(l7b87)
cp _String
jr nz,l4e24
ld b,a
call StImm ; Set POP IY
db a_L5
s_I5:
POP IY
a_L5 equ $-s_I5
ld a,_LD.HL
call StCode ; Set LD HL,val16
ld hl,l053a
call StCALL_ ; move string to stack
call StImm
db a_L6
s_I6:
PUSH IY
a_L6 equ $-s_I6
jr l4e46
l4e24:
cp _Real
jr nz,l4e35
ld a,_LD.HL
call StCode ; Set LD HL,val16
ld hl,l052c
call StCALL_ ; Set load real
jr l4e46
l4e35:
ld a,_LD_a_HL
call StCode ; Set LD HL,(adr16)
ld a,(l7b88)
dec a
jr nz,l4e46
call StImm ; Set LD H,0
db a_L7
s_I7:
LD H,0
a_L7 equ $-s_I7
l4e46:
ld hl,(l7b83)
ld a,h
or l
jr z,l4e74
ld de,(l7b85)
sbc hl,de
jr z,l4e74
ld a,(l7b97)
or a ; Test PROCEDURE
jr z,l4e65 ; Yeap
ld a,(l7b87)
cp _String
ld a,_EXX
call nz,writebyte_a_addriy ; Set EXX
l4e65:
call StLD.BC ; Set LD BC,val16
ex de,hl
call StLD.DE ; Set LD DE,val16
ld hl,l0522
call StJP_ ; Set end of recursive routine
jr l4e79
l4e74:
call StImm ; Set RET
db a_L8
s_I8:
RET
a_L8 equ $-s_I8
l4e79:
call l6f48 ; Verify ;
pop de
pop hl
ld (LabPtr),hl ; Set label pointers
ld (PrevLabPtr),hl
pop hl
ld (CurLab),hl ; Restore current label pointer
ex de,hl
ret
;
; Process BEGIN
;
l4e8a:
ld hl,(LabPtr) ; Get label pointer
l4e8d:
ld de,(CurLab) ; Get current label pointer
or a
sbc hl,de
add hl,de
ret z ; End on level 0
inc hl
ld e,(hl)
inc hl
ld d,(hl)
add hl,de
ld a,(hl)
cp 6 ;_TxtF???
jr z,l4ea4
cp 5 ;_RecF???
jr nz,l4e8d
l4ea4:
push hl
dec hl
dec hl
l4ea7:
bit _MB,(hl) ; Find end of string
dec hl
jr z,l4ea7
ld a,(hl) ; Get type
or a
call ErrNZ ; Maybe undefined FORWARD
db _UndefFORW
pop hl
jr l4e8d
;
;
;
l4eb5:
ld hl,(LabPtr) ; Get label pointer
push hl
ld b,0
l4ebb:
push bc
ld d,_Ptr ; Set type
ld a,(l7b91) ; Get ???
ld e,a
call puttolabel_d_e ; Put to table
call GetLabel ; Get label
call puttolabel ; Store into table
call puttolabel_d_e ; Put to table
call puttolabel_d_e ; Twice
call SetLabPtr ; Set label pointer
pop bc
inc b
call l6f13 ; Test ,
jr z,l4ebb ; Yeap
pop hl
ret
;
;
;
l4edd:
ld hl,(LabPtr) ; Get label pointer
push hl
call l4f9b ; Get type
pop hl
call l5295
call FindStr ; Test ABSOLUTE
dw l7562
ld a,0
jr nz,l4f14 ; Nope
ld a,(l7b91) ; Get ???
or a
call ErrNZ
db _InvalABS
ld bc,256*_Ptr+0
call FndLABEL ; Find label
jr nz,l4f0c ; Nope
ld a,(hl)
ld (l7b8f),a
dec hl
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
jr l4f0f
l4f0c:
call _GetIntC ; Get integer constant
l4f0f:
ld (l7b7f),hl ; Store value
ld a,-1
l4f14:
ld (l7b90),a
ret
;
; Process variable on PROCEDURE and FUNCTION
;
l4f18:
call l4fc8 ; Get simple type
call ErrNZ ; Verify ok
db _TypeExp
xor a
ld (l7b90),a
ld a,(l7b8f)
or a
ret nz
ld a,(l7b5c) ; Get type
cp _RecF
ret c
cp _String
ret nc
call ERROR ; Files must be VAR
db _VarFile
;
;
;
l4f35:
call l4eb5
push hl
push bc
call l6f40 ; Verify :
xor a
ld (l7b8f),a
call l4edd
pop bc
ld a,(l7b90)
or a
jr z,l4f51
ld a,b
dec a
call ErrNZ ; Invalid ABSOLUTE
db _InvalABS
l4f51:
pop hl
l4f52:
push bc
push hl
ld a,(l7b8f)
ld hl,2
or a
jr nz,l4f60
ld hl,(l7b62) ; Get length of type
l4f60:
ex de,hl
ld a,(l7b91) ; Get ???
or a
jr nz,l4f72
ld a,(l7b90)
or a
jr nz,l4f72
call VarAlloc ; Allocate space
jr l4f7b
l4f72:
ld hl,(l7b7f)
push hl
add hl,de
ld (l7b7f),hl
pop hl
l4f7b:
ex de,hl
pop hl
dec hl
l4f7e:
dec hl
bit _MB,(hl)
jr z,l4f7e
dec hl
ld a,(l7b8f)
ld (hl),a
dec hl
ld (hl),d
dec hl
ld (hl),e
dec hl
ld de,(l7b5a) ; Get type table
ld (hl),d ; Store into
dec hl
ld (hl),e
dec hl
dec hl
dec hl
pop bc
djnz l4f52
ret
;
; Get a TYPE
;
l4f9b:
call l4fc8 ; Test simple type
ret z
call FindStr ; Skip possible PACKED
dw l7542
call l4fdb ; Check ARRAY
ret z
call l5039 ; Check RECORD
ret z
call l5106 ; Check SET
ret z
call l5140 ; Check ^
ret z
call l516b ; Check FILE
ret z
call l51a5 ; Check STRING
ret z
call l51c5 ; Test SCALAR ()
ret z
call l5210 ; Test RANGE ..
ret z
call ERROR ; Type declaration expected
db _TypeExp
;
; Get SIMPLE TYPE
; EXIT Zero set if found
;
l4fc8:
ld bc,256*3+0
call FndLABEL ; Get from table
ret nz ; Not found
ld d,(hl) ; Fetch type table
dec hl
ld e,(hl)
ex de,hl
ld (l7b5a),hl ; Save type
call l5287 ; Get name
xor a ; Set success
ret
;
; Look for ARRAY
;
l4fdb:
call FindStr ; Test ARRAY
dw l7548
ret nz ; Nope
call l6f30 ; Verify [
ld b,0
l4fe6:
push bc
call l523b
pop bc
ld hl,(l7b5a) ; Get type table
push hl
ld hl,(l7b60) ; Get hi limit
ld de,(l7b5e) ; Get lo limit
or a
sbc hl,de
inc hl
ld a,h
or l
call ErrZ ; Verify not same
db _MemOvfl
push hl
inc b
call l6f13 ; Test ,
jr z,l4fe6 ; Yeap
push bc
call l6f38 ; Verify ]
call l6f88
call l4f9b ; Get type
pop bc
l5012:
ld hl,(l7b5a) ; Get type table
ld (l7b5e),hl ; Set as lo limit
ld hl,(l7b62) ; Get length of type
pop de
push bc
call l729a ; Multiply numbers
call ErrCY ; Check compiler overflow
db _MemOvfl
pop bc
ld (l7b62),hl ; Set length of type
pop hl
ld (l7b60),hl ; Set hi limit
ld a,_Array
ld (l7b5c),a ; Set ARRAY
push bc
call l5254 ; Put to table
pop bc
djnz l5012
ret
;
; Look for RECORD
;
l5039:
call FindStr ; Test RECORD
dw l7554
ret nz ; Nope
ld a,(l7b9a)
push af
ld a,(l7b91) ; Get ???
push af
ld hl,l7b92 ; Point to ???
inc (hl)
ld a,(hl)
ld (l7b91),a ; Set ???
ld hl,(l7b7f)
push hl
ld hl,(l7b81)
push hl
ld hl,l0000
ld (l7b7f),hl
ld (l7b81),hl
xor a
ld (l7b9a),a
call l508b
ld hl,(l7b81)
ld (l7b62),hl ; Set length of type
pop hl
ld (l7b81),hl
pop hl
ld (l7b7f),hl
ld a,(l7b91) ; Get ???
ld (l7b5d),a
pop af
ld (l7b91),a ; Set ???
pop af
ld (l7b9a),a
ld a,_Record
ld (l7b5c),a ; Set RECORD
jp l5254
;
;
;
l508b:
call l50f9
ret z
call FindStr ; Test CASE
dw l75da
jr z,l50b0 ; Yeap
call l4f35
ld hl,(l7b7f)
ld de,(l7b81)
or a
sbc hl,de
jr c,l50a9
add hl,de
ld (l7b81),hl
l50a9:
call l6f0f ; Test ;
jr z,l508b ; Yeap
jr l50e8
l50b0:
call l4fc8
call nz,l4f35
call l6f88
l50b9:
call l50f9
ret z
ld hl,(l7b7f)
push hl
l50c1:
call _GetConst ; Get constant
call l6f13 ; Test ,
jr z,l50c1 ; Yeap
call l6f40 ; Verify :
call l6f66 ; Verify (
ld a,(l7b9a)
push af
ld a,0ffh
ld (l7b9a),a
call l508b
pop af
ld (l7b9a),a
pop hl
ld (l7b7f),hl
call l6f0f ; Test ;
jr z,l50b9 ; Yeap
l50e8:
ld a,(l7b9a)
or a
jp nz,l6f6e ; Verify )
call FindStr ; Find END
dw l7530
ret z ; Yeap
call ERROR
db _End
l50f9:
ld a,(l7b9a)
or a
jp nz,l6f1f
call FindStr ; Find END
dw l7530
ret
;
; Check SET
;
l5106:
call FindStr ; Test SET
dw l7551
ret nz ; Nope
call l6f88
call l523b
ld hl,(l7b60) ; Get hi set limit
ld de,(l7b5e) ; Get lo set limit
ld a,h
or d
call ErrNZ
db _IllSetRange
srl l
srl l
srl l
srl e
srl e
srl e
ld a,l
inc a
sub e
ld l,a
ld (l7b62),hl ; Set length of type
ld hl,(l7b5a) ; Get type table
ld (l7b5e),hl ; Set lo set limit
ld a,_Set
ld (l7b5c),a ; Set SET
jp l5254
;
; Check ^
;
l5140:
call l6f27
ret nz
ld de,l0000
call puttolabel_d_e ; Put to table
ld hl,(LabPtr) ; Get label pointer
push hl
call l6dba
call SetLabPtr ; Set label pointer
pop hl
ld (l7b5e),hl ; Set lo set limit
ld a,_Ptr
ld (l7b5c),a ; Set POINTER
ld a,0ffh
ld (l7b5d),a
ld hl,l0002
ld (l7b62),hl ; Set length of type
jp l5254
;
; Check FILE
;
l516b:
call FindStr ; Find FILE
dw l754d
ret nz ; Nope
call FindStr ; Find OF
dw l7560
jr nz,l5197 ; Nope
call l4f9b ; Get type
ld a,(l7b5c) ; Get type
cp _RecF
jr c,l518a
cp _String
jr nc,l518a
call ERROR
db _FileF
l518a:
ld hl,(l7b5a) ; Get type table
ld (l7b5e),hl ; Set lo set limit
ld a,_RecF
ld hl,l00b0
jr l519c
l5197:
ld a,_UntF
ld hl,l0030
l519c:
ld (l7b5c),a ; Set type
ld (l7b62),hl ; Set length of type
jp l5254
;
; Check STRING
;
l51a5:
call FindStr ; Find STRING
dw l755a
ret nz ; Nope
call l6f30 ; Verify [
call _GetIntC ; Get integer constant
inc h
dec h
call ErrNZ
db _IllStrgLen
inc l
dec l
call ErrZ
db _IllStrgLen
call l6f38 ; Verify ]
inc hl
ld a,_String
jr l519c
;
; Test SCALAR ()
;
l51c5:
call l6f1b ; Test (
ret nz ; Nope
ld hl,lffff
l51cc:
push hl
ld de,2*256+0 ;l0200
call puttolabel_d_e ; Put to table
call GetLabel ; Get label
ld a,(curtype_l7b93) ; Get type
call puttolabel
pop de
inc de
push de
call puttolabel_d_e ; Put to table
call SetLabPtr ; Set label pointer
pop hl
call l6f13 ; Test ,
jr z,l51cc ; Yeap
call l6f6e ; Verify )
push hl
ld hl,curtype_l7b93 ; Point to type
ld a,(hl)
inc (hl)
pop hl
ld de,l0000
l51f8:
ld (l7b5c),a ; Set type
ld (l7b5e),de ; Set lo set limit
ld (l7b60),hl ; Set hi set limit
ld a,d
or h
ld hl,l0001
jr z,l520a
inc hl
l520a:
ld (l7b62),hl ; Set length of type
jp l5254
;
; Test RANGE ..
;
l5210:
call GetConst ; Get constant
ret nz
ld a,b
push af
cp 0ah ;_Integ
call ErrCY
db _IllSkalar
push hl
call FindStr ; Find ..
dw l7580
call ErrNZ
db _TwoDots
call _GetConst ; Get constant
pop de
pop af
push af
cp b
call ErrNZ
db _InvType
call l728d ; Compare
call ErrCY ; Verify upper > lower
db _IllLimit
pop af
jr l51f8
;
;
;
l523b:
call l5210
ret z
call l51c5
ret z
call l4fc8
call ErrNZ
db _SimTyp
ld a,(l7b5c) ; Get type
cp _Integ
ret nc
call ERROR
db _SimTyp
l5254:
ld de,8*256+0 ;l0800
call puttolabel_d_e ; Put to table
ld hl,(LabPtr) ; Get label pointer
ld (l7b5a),hl ; Save into type table
ld hl,l7b5c ; Point to type
ld b,8
l5265:
ld a,(hl)
call puttolabel
inc hl
djnz l5265
call SetLabPtr ; Set label pointer
xor a
ret
;
;
;
l5271:
ld de,l7b69
jr l528a
;
; Get values and name
;
l5276:
ld a,(hl)
dec hl
ld (Envir1),a
ld d,(hl)
dec hl
ld e,(hl)
dec hl
ld (l7b58),de ; Set value
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
;
; Get name
;
l5287:
ld de,l7b5c ; Point to type
l528a:
push bc
ld b,8
l528d:
ld a,(hl)
ld (de),a
dec hl
inc de
djnz l528d
pop bc
ret
;
;
;
l5295:
ld (l7b79),hl
ld hl,(LabPtr) ; Get label pointer
l529b:
ld bc,(l7b79)
or a
sbc hl,bc
add hl,bc
ret z
inc hl
ld c,(hl)
inc hl
ld b,(hl)
add hl,bc
ld a,(hl)
cp 8 ;???
jr nz,l529b
ld (hl),0
push hl
dec hl
dec hl
ld a,(hl)
cp 4 ;???
jr nz,l52f8
dec hl
ld a,(hl)
or a
jr z,l52f8
ld (hl),0
dec hl
push hl
ld e,(hl)
dec hl
ld d,(hl)
ld hl,(LabPtr) ; Get label pointer
l52c7:
ld bc,(l7b77) ; Get top of available memory
or a
sbc hl,bc
add hl,bc
call ErrZ
db _InkPointer
inc hl
ld c,(hl)
inc hl
ld b,(hl)
add hl,bc
ld a,(hl)
cp 3 ;???
jr nz,l52c7
push hl
push de
dec hl
dec hl
l52e1:
ld a,(de)
cp (hl)
jr z,l52e9
pop de
pop hl
jr l52c7
l52e9:
bit 7,(hl)
dec hl
dec de
jr z,l52e1
pop bc
pop bc
ld b,(hl)
dec hl
ld c,(hl)
pop hl
ld (hl),c
dec hl
ld (hl),b
l52f8:
pop hl
jp l529b
;
;
;
l52fc:
xor a
ld (l7b95),a
ld (l7bc9),a
call l5377
ld (l7ba4),iy
call StJP_
ld hl,(LabPtr) ; Get label pointer
l5310:
ld de,(PrevLabPtr) ; Get previous label pointer
or a
sbc hl,de
add hl,de
jr nc,l5363
inc hl
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld a,(hl)
inc hl
ld e,(hl)
inc hl
ld d,(hl)
push hl
push bc
ld b,a
ld a,d
or e
jr z,l533a
ex de,hl
dec hl
ld a,(hl)
ld c,a
inc a
call ErrZ
db _UnkLabel
dec hl
ld d,(hl)
dec hl
ld e,(hl)
jr l5340
l533a:
ld de,(l7ba4)
ld c,0
l5340:
pop hl
ld a,b
sub c
jr nz,l534a
call storeback_de_to_addrhl
jr l5360
l534a:
call ErrCY
db _IllGOTO
push de
push af
call storeback_iy_to_addrhl ; Store back PC
pop af
ld b,a
l5355:
call StPOP ; Set POP HL
djnz l5355
ld a,_JP
pop hl
call StCode
l5360:
pop hl
jr l5310
l5363:
ld hl,(l7ba4)
inc hl
push iy
pop de
dec de
dec de
or a
sbc hl,de
add hl,de
jp nz,storeback_iy_to_addrhl ; Store back PC
dec hl
jp ChkChn ; Check chaining
;
; Statement BEGIN
;
l5377:
call l5385 ; Process a statement
call FindStr ; Find END
dw l7530
ret z
call l6f50
jr l5377
;
; Process a statement
;
l5385:
ld a,0ffh
ld (l7b98),a
ld a,(l7b9d) ; Get options
ld (l7b9e),a ; Set local options
bit _Uopt,a ; Test $U+
jr z,l539c ; Nope
ld a,RST
ld (l7ba0),a ; Set end on break flag [option U+]
call writebyte_a_addriy ; Insert RST
l539c:
call FndTabStr ; Find statement
db 2
dw l75bb
jr z,l53cb ; Yeap
call l67b2
jp z,l57ea
ld bc,256*5+0
call FndLABEL
jp z,l573d
ld bc,256*1+0
call FndLABEL
jr z,l53d0
ld bc,256*6+0
call FndLABEL
jp z,l591f
call FndTabStr ; Find procedure
db 2
dw l7638
ret nz ; Nope
l53cb:
ld e,(hl) ; Fetch address
inc hl
ld d,(hl)
ex de,hl
jp (hl) ; Go
l53d0:
call l6f40 ; Verify :
ld a,(l7b94) ; Get ???
cp (hl)
call ErrNZ
db _IllLabel
dec hl
ld a,(hl)
inc a
call ErrNZ
db _DoubleLab
ld a,(l7b95)
ld (hl),a
push iy
pop de
dec hl
ld (hl),d
dec hl
ld (hl),e
jr l5385
;
; Statement IF
;
l53ef:
call l5eb0
call StImm ; Set BIT 0,L ! JP Z,addr
db a_L9
s_I9:
BIT _LB,L
db _JPZ
a_L9 equ $-s_I9
push iy
call writeword_hl_addriy
call FindStr ; Find THEN
dw l756a
call ErrNZ
db _StrIdx
call l5385 ; Process a statement
call FindStr ; Find ELSE
dw l756e
jr nz,l5420 ; Nope
call StJP ; Set JP
pop hl
push iy
call writeword_hl_addriy
call storeback_iy_to_addrhl ; Store back PC
call l5385 ; Process a statement
l5420:
pop hl
jp storeback_iy_to_addrhl ; Store back PC
;
; Statement WHILE
;
l5424:
push iy
call l5eb0
call FindStr ; Find DO
dw l7572
call ErrNZ
db _NoDO
call StImm ; Set BIT 0,L ! JP Z,addr
db a_L10
s_I10:
BIT _LB,L
db _JPZ
a_L10 equ $-s_I10
push iy
call writeword_hl_addriy
call l5385 ; Process a statement
pop de
pop hl
ld a,_JP
call StCode
ex de,hl
jp storeback_iy_to_addrhl ; Store back PC
;
; Statement REPEAT
;
l544c:
push iy
l544e:
call l5385 ; Process a statement
call FindStr ; Find UNTIL
dw l7574
jr z,l545d ; Yeap
call l6f50
jr l544e
l545d:
call l5eb0
call StImm
db a_L11
s_I11:
BIT _LB,L
db _JPZ
a_L11 equ $-s_I11
pop hl
jp writeword_hl_addriy
;
; Statement FOR
;
l546b:
ld bc,256*4+0
call FndLABEL
call ErrNZ
db _Undef
call l5276
ld a,(Envir1)
or a
jr nz,l5485
ld a,(l7b5c) ; Get type
cp _Integ
jr nc,l5489
l5485:
call ERROR
db _SimTyp
l5489:
call l6d2a ; Save environment
ld a,(l7b5c) ; Get type
push af
call l6f7e
call l5ee8
call StPUSH ; Set PUSH HL
pop af
push af
cp b
call ErrNZ
db _InvType
call FndTabStr ; Find TO or DOWNTO
db 1
dw l75f5
call ErrNZ
db _NoDOWN_TO
ld e,(hl) ; Get instruction
push de
call l5ee8
pop de
pop af
push de
cp b
call ErrNZ
db _InvType
call FindStr ; Find DO
dw l7572
call ErrNZ
db _NoDO
call StImm ; Set POP DE
db a_L12
s_I12:
POP DE
a_L12 equ $-s_I12
pop de
call l6d63
push de
ld a,e
ld hl,l0666 ; Set up FOR .. TO loop
cp '#'
jr z,l54d5
ld hl,l0676 ; Set up FOR .. DOWNTO loop
l54d5:
call StCALL_ ; Set CALL <loop>
push iy
;jr $
call StImm ; Set code sequence
db a_L13
s_I13:
LD A,D
OR E
JP Z,$-$ ;for future patching???
PUSH DE
a_L13 equ $-s_I13
call l661b
ld hl,l7b95
inc (hl)
call l5385 ; Process a statement
ld hl,l7b95
dec (hl)
pop hl
pop de
call RestEnv1 ; Get back environment
push hl
ld hl,(l7b58) ; Get value
ld a,_LD_a_HL
call StCode
ld a,(l7b62) ; Get length of type
dec a
jr nz,l550c
call StImm ; Set LD H,0
db a_L14
s_I14:
LD H,0
a_L14 equ $-s_I14
l550c:
ld a,e ; Get byte
call writebyte_a_addriy ; Store it
call StImm ; Set code sequence
db a_L15
s_I15:
POP DE
DEC DE
db _JP
a_L15 equ $-s_I15
pop hl
call writeword_hl_addriy
inc hl
inc hl
inc hl
jp storeback_iy_to_addrhl ; Store back PC
;
; Statement CASE
;
l5521:
call l5ebb
ld (l7b9c),a
xor a
ld (l7b9b),a
call l6f88
ld b,0
push bc
l5531:
ld b,1
l5533:
push bc
ld hl,l7b9b
bit 7,(hl)
jr z,l5549
call StImm ; Set ADD HL,DE
db a_L16
s_I16:
ADD HL,DE
a_L16 equ $-s_I16
bit 4,(hl)
jr z,l5549
call StImm ; Set ADD HL,BC
db a_L17
s_I17:
ADD HL,BC
a_L17 equ $-s_I17
l5549:
call _GetConst ; Get constant
ld a,(l7b9c)
cp b
call ErrNZ
db _IllCASE
call StLD.DE ; Set LD DE,val16
push hl
call FindStr ; Find ..
dw l7580
pop hl
jr nz,l5582 ; Nope
push hl
call _GetConst ; Get constant
ld a,(l7b9c)
cp b
call ErrNZ
db _IllCASE
pop de
or a
sbc hl,de
inc hl
call StLD.BC
call StImm ; Set sequence
db a_L18
s_I18:
OR A
SBC HL,DE
OR A
SBC HL,BC
a_L18 equ $-s_I18
ld a,0dah
jr l558b
l5582:
call StImm ; Set sequence
db a_L19
s_I19:
OR A
SBC HL,DE
a_L19 equ $-s_I19
ld a,0cah
l558b:
ld (l7b9b),a
call l6f0b ; Test :
pop bc
jr z,l55a5
ld a,(l7b9b) ; Get byte
call writebyte_a_addriy ; Store it
push iy
call writeword_hl_addriy
call l6f5e ; Verify ,
inc b
jr l5533
l55a5:
push iy
pop de
inc de
inc de
inc de
l55ab:
dec b
jr z,l55b4
pop hl
call storeback_de_to_addrhl
jr l55ab
l55b4:
ld a,(l7b9b) ; Get byte
res 3,a ; Fix it
call writebyte_a_addriy ; Store
pop bc
push iy
inc b
push bc
call writeword_hl_addriy
ld a,(l7b9b)
push af
ld a,(l7b9c)
push af
call l5385 ; Process a statement
pop af
ld (l7b9c),a
pop af
ld (l7b9b),a
call l6f0f ; Test ;
ld e,1
jr z,l55df ; Yeap
dec e
l55df:
push de
call FindStr ; Find END
dw l7530
pop de
jr z,l561e
call StJP ; Set JP
pop bc
pop hl
push iy
push bc
push de
call writeword_hl_addriy
call storeback_iy_to_addrhl ; Store back PC
call FindStr ; Find ELSE
dw l756e
pop de
jr z,l560f ; Yeap
dec e
jp z,l5531
ld a,(l7b98)
or a
call ErrZ
db _End
call ERROR
db _Undef
l560f:
call l5385 ; Process a statement
call FindStr ; Find END
dw l7530
jr z,l561e ; Yeap
call l6f50
jr l560f
l561e:
pop bc
l561f:
pop hl
call storeback_iy_to_addrhl ; Store back PC
djnz l561f
ret
;
; Statement GOTO
;
l5626:
ld bc,256*1+0
call FndLABEL
call ErrNZ
db _UnkLabel
ld a,(l7b94)
cp (hl)
call ErrNZ
db _IllLabel
ex de,hl
l5639:
call puttolabel_d_e ; Put to table
ld a,(l7b95)
call puttolabel
call StJP ; Set JP
push iy
pop de
call puttolabel_d_e ; Put to table
jp writeword_hl_addriy
;
; Statement WITH
;
l564e:
ld a,(l7bc9)
push af
l5652:
ld a,(l7bc6)
ld hl,l7bc9
cp (hl)
call ErrZ
db _TooManyWITH
call l677f
ld a,(l7b5c) ; Get type
cp _Record
call ErrNZ
db _RecVarExp
ld hl,l7bc9
ld e,(hl)
ld d,0
inc (hl)
ld hl,l7bcc
add hl,de
ld a,(l7b5d)
ld (hl),a
ld hl,(l7bca)
add hl,de
add hl,de
ld a,_LDHL_a
call StCode
call l6f13 ; Test ,
jr z,l5652 ; Yeap
call FindStr ; Find DO
dw l7572
call ErrNZ
db _NoDO
call l5385 ; Process a statement
pop af
ld (l7bc9),a
ret
;
; Statement INLINE
;
l5698:
call l6f66 ; Verify (
l569b:
ld a,'>'
call l6f29
ld a,2
jr z,l56ae
ld a,'<'
call l6f29
ld a,1
jr z,l56ae
xor a
l56ae:
ld (l7ba6),a
xor a
ld h,a
ld l,a
ld b,a
l56b5:
push bc
push hl
call GetConst ; Get constant
jr nz,l56c5
ld a,b
cp 0ah
jr z,l5702
call ERROR
db _IntConst
l56c5:
ld hl,l7ba6
ld a,(hl)
or a
jr nz,l56ce
ld (hl),2
l56ce:
ld a,'*'
call l6f29
jr nz,l56da
push iy
pop hl
jr l5702
l56da:
ld bc,256*4+0
call FndLABEL
jr nz,l56ea
call l5276
ld hl,(l7b58) ; Get value
jr l5702
l56ea:
ld bc,256*5+0
call FndLABEL
jr z,l56fc
ld bc,256*6+0
call FndLABEL
call ErrNZ
db _IllINLINE
l56fc:
dec hl
dec hl
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
l5702:
pop de
pop bc
dec b
jr nz,l570a
call NegateInt
l570a:
add hl,de
ld b,0
ld a,'+'
call l6f29
jr z,l56b5
inc b
ld a,'-'
call l6f29
jr z,l56b5
ld a,(l7ba6)
cp 1
jr z,l5729
jr nc,l572f
inc h
dec h
jr nz,l572f
l5729:
ld a,l ; Get byte
call writebyte_a_addriy ; Store it
jr l5732
l572f:
call writeword_hl_addriy
l5732:
ld a,'/'
call l6f29
jp z,l569b
jp l6f6e ; Verify )
l573d:
dec hl
ld b,(hl)
dec hl
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push de
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push de
dec hl
dec hl
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push de
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push de
inc b
dec b
jp z,l57d6
call l6f66 ; Verify (
l575e:
push bc
ld b,(hl)
dec hl
ld a,(hl)
dec hl
ld (Envir1),a
ld d,(hl)
dec hl
ld e,(hl)
dec hl
ld c,b
l576b:
bit 7,(hl)
dec hl
jr z,l576b
djnz l576b
ld b,c
push hl
ex de,hl
call l5287 ; Get name
l5778:
push bc
ld a,(Envir1)
or a
jr nz,l57a9
ld a,(l7b5c) ; Get type
cp _Set
jr c,l57a1
call l5e84
call l5864
ld a,(l7b5c) ; Get type
cp _Ptr
jr z,l57bd
cp _Real
jr c,l57c0
jr nz,l57bd
call StImm ; Set sequence
db a_L20
s_I20:
PUSH BC
PUSH DE
a_L20 equ $-s_I20
jr l57bd
l57a1:
call l6d2a ; Save environment
call l6749
jr l57af
l57a9:
call l6d2a ; Save environment
call l677f
l57af:
call CpyEnv2
ld a,(l7b69)
cp 0
call nz,l58c5
call RestEnv1 ; Get back environment
l57bd:
call StPUSH ; Set PUSH HL
l57c0:
pop bc
dec b
jr z,l57c9
call l6f5e ; Verify ,
jr l5778
l57c9:
pop hl
pop bc
dec b
jr z,l57d3
call l6f5e ; Verify ,
jr l575e
l57d3:
call l6f6e ; Verify )
l57d6:
pop de
pop hl
ld a,d
or e
jr z,l57e3
call StLD.HL ; Set LD HL,val16
ex de,hl
call StLD.DE ; Set LD DE,val16
l57e3:
pop de
pop hl
ld a,_CALL
jp StCode
l57ea:
ld a,(l7b5c) ; Get type
cp 0
jr z,l57f9
cp _RecF
jr c,l57fd
cp _String
jr nc,l57fd
l57f9:
call ERROR
db _IllAss
l57fd:
ld a,(l7bbd)
bit 1,a
jr nz,l5812
bit 0,a
jr z,l580a
ld a,0ffh
l580a:
ld hl,(l7bbe)
ld (l7b58),hl ; Set value
jr l581a
l5812:
call l678b
call StPUSH ; Set PUSH HL
ld a,1
l581a:
ld (Envir1),a
call l6f7e
ld a,(l7b5c) ; Get type
cp _Set
jp nc,l593a
call l6d2a ; Save environment
call l6749
call RestEnv2
call l58c5
ld a,(Envir2)
dec a
jr z,l5852
inc a
jr z,l5845
call StImm ; Set LD DE,(adr)
db a_L21
s_I21:
dw _LD_a_DE
a_L21 equ $-s_I21
jr l584a
l5845:
call StImm
db a_L22
s_I22:
db _LD.DE ; Set LD DE,adr
a_L22 equ $-s_I22
l584a:
ld hl,(l7b65)
call writeword_hl_addriy
jr l5857
l5852:
call StImm ; Set POP DE
db a_L23
s_I23:
pop de
a_L23 equ $-s_I23
l5857:
ld hl,(l7b6f)
call StLD.BC
call StImm ; Set LDIR
db a_L24
s_I24:
LDIR
a_L24 equ $-s_I24
ret
l5864:
ld a,(l7b5c) ; Get type
cp _Real
jr nz,l5877
ld a,b
cp _Integ
jr nz,l589d
ld b,9
ld hl,l1008
jr l589a
l5877:
cp _String
jr nz,l588c
ld a,b
cp _Char
jr nz,l589d
ld b,8
call StImm ; Set sequence
db a_L25
s_I25:
LD H,L
LD L,1
PUSH HL
a_L25 equ $-s_I25
jr l589d
l588c:
cp _Char
jr nz,l589d
ld a,b
cp _String
jr nz,l589d
ld b,0ch
ld hl,l0996 ; Set check assignment
l589a:
call StCALL_ ; Set CALL <check>
l589d:
ld a,(l7b5c) ; Get type
cp b
jr nz,l58c1
cp 3
jr nz,l58b1
ld a,c
or a
ret z
ld hl,(l7b5e) ; Get lo set limit
cp (hl)
ret z
jr l58c1
l58b1:
cp 4
ret nz
ld hl,(l7b8b)
ld a,h
or l
ret z
ld de,(l7b5e) ; Get lo set limit
sbc hl,de
ret z
l58c1:
call ERROR
db _InvType
l58c5:
ld a,(l7b5c) ; Get type
cp 0
jr z,l591b
ld c,0bfh
cp _Integ
jr nc,l5906
ld c,83h
cp _String
jr nz,l58e3
ld a,(l7b9e) ; Get local options
bit _Vopt,a ; Test $V+
jr nz,l5906 ; Yeap
ld c,80h
jr l5906
l58e3:
cp _TxtF
jr nc,l5906
ld c,0b3h
cp _Set
jr nc,l5906
ld c,0c3h
cp _Record
jr nc,l5906
ld hl,(l7b60) ; Get hi set limit
ld a,h
or l
ld c,0bfh
jr nz,l5906
ld hl,(l7b6d) ; Get last memory address
ld a,(hl)
cp 0ah
jr nz,l591b
ld c,0b3h
l5906:
ld hl,l7b5c ; Point to type
ld de,l7b69
ld b,8
l590e:
rl c
jr nc,l5916
ld a,(de)
cp (hl)
jr nz,l591b
l5916:
inc hl
inc de
djnz l590e
ret
l591b:
call ERROR
db _InvType
l591f:
ld de,lfffc
add hl,de
ld d,(hl)
dec hl
ld e,(hl)
dec hl
push de
ld d,(hl)
dec hl
ld e,(hl)
ld (l7b58),de ; Set value
pop hl
call l5287 ; Get name
xor a
ld (Envir1),a
call l6f7e
l593a:
call l5e84
call l5864
jp l661b
;
; Procedure ASSIGN(FileVar,String)
;
l5943:
call l5a0c
ld hl,l1370
cp 6
jr nz,l5955
ld hl,l136f
call l5955
jr l5989
l5955:
push hl
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5ed0
pop hl
l5960:
call l6f6e ; Verify )
jp StCALL_ ; Set CALL <...>
;
; Procedure RENAME(FileVar,String)
;
l5966:
call l5a0c
ld hl,l1ba5
call l5955
jr l5989
;
; Procedure ERASE(FileVar)
;
l5971:
call l5a0c
ld hl,l1b93
jr l5960
;
; Procedure CHAIN(FileVar)
;
l5979:
ld hl,l1beb
jr l5981
;
; Procedure EXECUTE(FileVar)
;
l597e:
ld hl,l1bea
l5981:
push hl
call l5a0c
l5985:
pop hl
l5986:
call l5960
l5989:
jp l5abe
;
; Procedure SEEK(FileVar,Integer)
;
l598c:
call l5a0c
cp 6
call ErrZ
db _IllTxtFile
ld hl,l19d5
cp 5
jr z,l599f
ld hl,l1b6f
l599f:
push hl
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
jr l5985
;
; Procedure FLUSH(FileVar)
;
l59ab:
call l5a0c
cp 5
call ErrNZ
db _IllFileType
ld hl,l19a5
jr l5986
;
; Procedure RESET(FileVar,String)
;
l59b9:
ld hl,l59fa
jr l59c1
;
; Procedure REWRITE(FileVar,String)
;
l59be:
ld hl,l5a00
l59c1:
push hl
call l5a0c
ld a,(l7b5c) ; Get type
cp _RecF
jr nz,l59d8
ld hl,(l7b5e) ; Get lo set limit
call l5271 ; Load name
ld hl,(l7b6f)
call StLD.DE ; Set LD DE,val16
l59d8:
pop hl
jr l59e1
;
; Procedure CLOSE(FileVar)
;
l59db:
call l5a0c
ld hl,l5a06
l59e1:
call l6f6e ; Verify )
call l59e9
jr l5989
l59e9:
ld a,(l7b5c) ; Get type
sub _RecF
add a,a
ld e,a
ld d,0
add hl,de
ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
jp StCALL_ ; Set CALL <...>
l59fa: ;reset procedures
dw l1811 ; Record file
dw l13ff ; Text file
dw l1a70 ; Untyped file
l5a00: ;rewrite procedures
dw l1810
dw l13fe
dw l1a6f
l5a06: ;close procedures
dw l187a
dw l1469
dw l1ab0
l5a0c:
call l6f66 ; Verify (
call l5a17
ret z
call ERROR
db _FileVarExp
l5a17:
call l67b2
scf
ret nz
ld a,(l7b5c) ; Get type
cp _RecF
jr c,l5a2f
cp _String
jr nc,l5a2f
call l678b
xor a
ld a,(l7b5c) ; Get back type
ret
l5a2f:
xor a
dec a
ret
;
; Procedure READLN(FileVar,Variables)
;
l5a32:
db skip
;
; Procedure READ(FileVar,Variables)
;
l5a33:
xor a
ld (l7ba3),a
call l6f1b ; Test (
jr z,l5a41 ; Yeap
call l5aca
jr l5ab4
l5a41:
call l5a17 ;get type???
jr c,l5a63
jr nz,l5a5b
cp 5 ;_RecF???
jp z,l5bd8
cp 6 ;_TxtF???
call ErrNZ
db _NoUntypeFile
ld hl,l14a9
call StCALL_ ; Set CALL FILECHECK
jr l5aac
l5a5b:
call l678b
call l5aca
jr l5a69
l5a63:
call l5aca
l5a66:
call l677f
l5a69:
ld a,(l7b5c) ; Get type
cp _String
jr c,l5a78
cp _Bool
jr z,l5a78
cp _Char+1
jr c,l5a7c
l5a78:
call ERROR
db _InvIO
l5a7c:
cp _String
jr nz,l5a8f
ld a,(l7b62) ; Get length of type
dec a
ld h,a
ld l,6
call writeword_hl_addriy
ld hl,l168e
jr l5aa9
l5a8f:
ld hl,l1672
cp _Real
jr z,l5aa9
ld hl,l1644
cp _Char
jr z,l5aa9
ld hl,l164e
ld a,(l7b62) ; Get length of type
dec a
jr nz,l5aa9
ld hl,l164d
l5aa9:
call StCALL_ ; Set CALL <read>
l5aac:
call l6f13 ; Test ,
jr z,l5a66 ; Yeap
call l6f6e ; Verify )
l5ab4:
ld hl,l16ab
l5ab7:
ld a,(l7ba3)
or a
call nz,StCALL_ ; Set CALL NEWLINE
l5abe:
ld a,(l7b9e) ; Get local options
bit _Iopt,a ; Test $I+
ret z ; Nope
ld hl,l201b
jp StCALL_ ; Set CALL CHECKIO
l5aca:
ld hl,l149b
ld a,(l7b9e) ; Get local options
bit _Bopt,a ; Test $B+
jr z,l5ae4 ; Nope
ld hl,l14cc
ld a,(l7ba3)
or a
jr z,l5ae4
ld hl,l14cb
xor a
ld (l7ba3),a
l5ae4:
jp StCALL_ ; Set CALL <read>
;
; Procedure WRITELN(FileVar,Variables)
;
l5ae7:
db skip
;
; Procedure WRITE(FileVar,Variables)
;
l5ae8:
xor a
ld (l7ba3),a
call l6f1b ; Test (
jr z,l5afa ; Yeap
ld hl,l149b
call StCALL_ ; Set CALL STDIO
jp l5bd2
l5afa:
call l5a17
jr c,l5b20
jr nz,l5b15
cp 5
jp z,l5bdd
cp 6
call ErrNZ
db _NoUntypeFile
ld hl,l14ba
call StCALL_ ; Set CALL CHECKWRFILE
jp l5bc9
l5b15:
call l620f
ld hl,l149b
call StCALL_ ; Set CALL STDIO
jr l5b4f
l5b20:
ld hl,l149b
call StCALL_ ; Set CALL STDIO
l5b26:
call GetLabType
jr nz,l5b4c
ld a,b
cp 8 ;_String???
jr nz,l5b47
ld a,(ix+0)
cp ','
jr z,l5b3b
cp ')'
jr nz,l5b47
l5b3b:
ld hl,l17ba
call StCALL_ ; Set CALL IMSTRG
call StLen
jp l5bc9
l5b47:
call l6201
jr l5b4f
l5b4c:
call l5ee8
l5b4f:
ld a,b
cp 8 ;0..7: _Array,_Record,_Set,_Ptr,_RecF,_TxtF,_UntF
jr c,l5b58 ;not a scalar type???
cp 0dh ;element of a set???
jr c,l5b5c ;8..12: (_String excluded above),_Real,_Integ,_Bool,_Char
l5b58:
call ERROR
db _InvIO
l5b5c:
cp 0ch ;_Char???
jr nz,l5b6a
call l6f0b ; Test :
jr nz,l5ba6
call l5edd
jr l5b72
l5b6a:
call l6148
call l6f0b ; Test :
jr nz,l5b8b
l5b72:
push bc
call l5e97
pop bc
ld a,b
cp 9 ;_Real???
jr nz,l5ba6
call l6f0b ; Test :
jr nz,l5b9d
push bc
call StPUSH ; Set PUSH HL
call l5e97
pop bc
jr l5ba6
l5b8b:
ld hl,l0000
ld a,b
cp 9 ;_Real???
jr nz,l5b95
ld l,12h
l5b95:
call StLD.HL ; Set LD HL,val16
ld a,b
cp 9 ;_Real???
jr nz,l5ba6
l5b9d:
call StPUSH ; Set PUSH HL
ld hl,lffff
call StLD.HL ; Set LD HL,val16
l5ba6:
ld a,b
ld hl,l17aa
cp 8 ;_String???
jr z,l5bc6
ld hl,l1779
cp 9 ;_Real???
jr z,l5bc6
ld hl,l1726
cp 0ah ;_Integ???
jr z,l5bc6
ld hl,l178b
cp 0bh ;_Bool???
jr z,l5bc6
ld hl,l1722
l5bc6:
call StCALL_ ; Set CALL <wrtype>
l5bc9:
call l6f13 ; Test ,
jp z,l5b26 ; Yeap
call l6f6e ; Verify )
l5bd2:
ld hl,l17cd
jp l5ab7
l5bd8:
ld hl,l18b6
jr l5be0
l5bdd:
ld hl,l18dc
l5be0:
ld (l7ba7),hl
ld a,(l7ba3)
or a
call ErrNZ
db _MustTextFile
ld hl,l18a4
call StCALL_ ; Set CALL PREPRECWR
ld hl,(l7b5e) ; Get lo set limit
call l5271 ; Load name
l5bf7:
call l6f13 ; Test ,
jr nz,l5c10 ; Nope
call SavEnv2
call l677f
call RestEnv2
call l58c5
ld hl,(l7ba7)
call StCALL_ ; Set CALL <write>
jr l5bf7
l5c10:
call l6f6e ; Verify )
jp l5abe
;
; Procedure BLOCKREAD(FileVar,Variable,Integer[,Integer])
;
l5c16:
ld hl,l1af1
ld de,l1abe
jr l5c24
;
; Procedure BLOCKWRITE(FileVar,Variable,Integer[,Integer])
;
l5c1e:
ld hl,l1aed
ld de,l1aba
l5c24:
push hl
push de
call l5a0c
cp 7
call ErrNZ
db _UntFileExp
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l677f
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
call l6f13 ; Test ,
pop de
pop hl
jr z,l5c4b ; Yeap
push de
jr l5c63
l5c4b:
push hl
call StPUSH ; Set PUSH HL
call l677f
ld a,(l7b5c) ; Get type
cp _Integ
jr nz,l5c5f
ld a,(l7b62) ; Get length of type
dec a
jr nz,l5c63
l5c5f:
call ERROR
db _IntVarExp
l5c63:
jp l5985
;
; Procedure DELETE(String,Integer,Integer)
;
l5c66:
call l6f66 ; Verify (
call l5cad
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
ld hl,l08f3 ; Set DELETE
l5c81:
call l6f6e ; Verify )
jp StCALL_ ; Set CALL <string_procedure>
;
; Procedure INSERT(String,String,Integer)
;
l5c87:
call l6f66 ; Verify (
call l5ed0
call l6f5e ; Verify ,
call l5cad
call StPUSH ; Set PUSH HL
ld a,(l7b62) ; Get length of type
dec a
ld h,a
ld l,6
push hl
call l6f5e ; Verify ,
call l5e97
pop hl
call writeword_hl_addriy
ld hl,l0920
jr l5c81 ; Set INSERT
l5cad:
call l677f
ld a,(l7b5c) ; Get type
cp _String
ret z
call ERROR
db _StrgVarExp
;
; Procedure STR(Num,String)
;
l5cba:
call l6f66 ; Verify (
call l5ea2
call l6148
call l6f0b ; Test :
jr nz,l5ce4
push bc
call l5e97
call StPUSH ; Set PUSH HL
pop bc
ld a,b
cp 0ah
jr z,l5d02
call l6f0b ; Test :
jr nz,l5cf9
push bc
call l5e97
call StPUSH ; Set PUSH HL
pop bc
jr l5d02
l5ce4:
ld hl,l0000
ld a,b
cp 0ah
jr z,l5cee
ld l,12h
l5cee:
call StLD.HL ; Set LD HL,val16
call StPUSH ; Set PUSH HL
ld a,b
cp 0ah
jr z,l5d02
l5cf9:
ld hl,lffff
call StLD.HL ; Set LD HL,val16
call StPUSH ; Set PUSH HL
l5d02:
call l6f5e ; Verify ,
push bc
call l5cad
ld a,(l7b62) ; Get length of type
dec a
ld h,a
ld l,6
call writeword_hl_addriy
pop bc
ld hl,l1ebe
ld a,b
cp 0ah
jr z,l5d1f
ld hl,l1ebd
l5d1f:
jp l5c81
;
; Procedure VAL(String,Integer,Integer)
;
l5d22:
call l6f66 ; Verify (
call l5ed0
call l6f5e ; Verify ,
call l677f
ld a,(l7b5c) ; Get type
cp _Real
jr z,l5d45
cp _Integ
jr nz,l5d41
ld a,(l7b62) ; Get length of type
dec a
ld a,0ah
jr nz,l5d45
l5d41:
call ERROR
db _NumVarExp
l5d45:
push af
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l677f
ld a,(l7b5c) ; Get type
cp _Integ
jr nz,l5d5c
ld a,(l7b62) ; Get length of type
dec a
jr nz,l5d60
l5d5c:
call ERROR
db _IntVarExp
l5d60:
pop af
ld hl,l1ef4
cp 0ah
jr z,l5d1f
ld hl,l1ef3
jr l5d1f
;
; Procedure GOTOXY(Integer,Integer)
;
l5d6d:
call l6f66 ; Verify (
call l5e97
ld hl,l1fdb
l5d76:
push hl
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
pop hl
jr l5db1
;
; Procedure RANDOMIZE
;
l5d83:
ld hl,l1f48
jp StCALL_ ; Set CALL RANDOMIZE
;
; Procedure DELAY(Integer)
;
l5d89:
call l6f66 ; Verify (
call l5e97
ld hl,l021d
jr l5db1 ; Set call to delay
;
; Procedure GETMEM(Variable,Integer)
;
l5d94:
call l5de3
call l6f5e ; Verify ,
call l5e97
jr l5dae
;
; Procedure NEW(Variable)
;
l5d9f:
call l5de3
ld hl,(l7b5e) ; Get lo set limit
call l5271 ; Load name
ld hl,(l7b6f)
call StLD.HL ; Set LD HL,val16
l5dae:
ld hl,l1ce5
l5db1:
jp l5960
;
; Procedure FREEMEM(Variable,Integer)
;
l5db4:
call l5de3
call l6f5e ; Verify ,
call l5e97
jr l5dce
;
; Procedure DISPOSE(Variable)
;
l5dbf:
call l5de3
ld hl,(l7b5e) ; Get lo set limit
call l5271 ; Load name
ld hl,(l7b6f)
call StLD.HL ; Set LD HL,val16
l5dce:
ld hl,l1d7a
jp l5960
;
; Procedure MARK(Variable)
;
l5dd4:
ld hl,l1ea3
jr l5ddc
;
; Procedure RELEASE(Variable)
;
l5dd9:
ld hl,l1eab
l5ddc:
push hl
call l5de9
pop hl
jr l5db1
l5de3:
call l5de9
jp StPUSH ; Set PUSH HL
l5de9:
call l6f66 ; Verify (
call l677f
ld a,(l7b5c) ; Get type
cp _Ptr
ret z
call ERROR
db _PtrVarExp
;
; Procedure OVRDRIVE(Integer)
;
l5df9:
call l6f66 ; Verify (
call l5e97
ld hl,l1cdb
jp l5960
;
; Procedure MOVE(Integer,Integer,Integer)
;
l5e05:
call l6f66 ; Verify (
call l677f
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l677f
ld hl,l1f64
jp l5d76
;
; Procedure FILLCHAR(Integer,Integer,Byte)
;
l5e1a:
call l6f66 ; Verify (
call l677f
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5e97
call StPUSH ; Set PUSH HL
call l6f5e ; Verify ,
call l5ebb
ld hl,l1f4e
jp l5db1
;
; Procedure CRTINIT
;
l5e38:
ld hl,l030a
jr l5e45 ; Set call to lead in
;
; Procedure CRTEXIT
;
l5e3d:
ld hl,l0310
jr l5e45 ; Set call to lead out
;
; Procedure CLRSCR
;
l5e42:
ld hl,l023e ; Set call to clear screen
l5e45:
jp StCALL_ ; Set CALL <crt_procedure>
;
; Procedure CLREOL
;
l5e48:
ld hl,l0299 ; Set call to clear to end of line
jr l5e45
;
; Procedure NORMVIDEO or HIGHVIDEO
;
l5e4d:
ld hl,setnormvideo ; Set call to normal video
jr l5e45
;
; Procedure LOWVIDEO
;
l5e52:
ld hl,setlowvideo ; Set call to low video
jr l5e45
;
; Procedure INSLINE
;
l5e57:
ld hl,l0262 ; Set call to insert line
jr l5e45
;
; Procedure DELLINE
;
l5e5c:
ld hl,l0259 ; Set call to delete line
jr l5e45
;
; Procedure EXIT
;
l5e61:
ld de,OS ; Set call to exit
jp l5639
;
; Procedure HALT
;
l5e67:
ld hl,l20d4
jp StJP_ ; Set call to HALT program
;
; Procedure PORT(Integer,Integer)
;
l5e6d:
call l5e8e
call StImm ; Set sequence
db a_L26
s_I26:
POP BC
OUT (C),L
a_L26 equ $-s_I26
ret
;
; Procedure STACKPTR
;
l5e78:
call l6f7e
call l5e97
call StImm ; Set LD SP,HL
db a_L27
s_I27:
LD SP,HL
a_L27 equ $-s_I27
ret
l5e84:
call l6d2a ; Save environment
call l5ee8
call RestEnv1 ; Get back environment
ret
l5e8e:
call l65d5
call l6f7e
call StPUSH ; Set PUSH HL
l5e97:
call l5ee8
ld a,b
cp 0ah
ret z
call ERROR
db _IntExpr
l5ea2:
call l5ee8
ld a,b
cp 0ah
ret z
cp 9
ret z
call ERROR
db _NumExprExp
l5eb0:
call l5ee8
ld a,b
cp 0bh
ret z
call ERROR
db _BoolExp
l5ebb:
call l5ee8
l5ebe:
ld a,b
cp 0ah
ret nc
cp 8
call ErrNZ
db _SimpExpr
ld b,0ch
ld hl,l0996
jp StCALL_ ; Set CALL CHECKASSIGNMENT
l5ed0:
call l5ee8
ld a,b
cp 8
ret z
cp 0ch
call ErrNZ
db _StrgExpExp
l5edd:
ld b,8
call StImm ; Set sequence
db a_L28
s_I28:
LD H,L
LD L,1
PUSH HL
a_L28 equ $-s_I28
ret
l5ee8:
call l5f98
l5eeb:
push bc
call FndTabStr ; Find relation
db 1
dw l7625
pop bc
ret nz ; Nope
ld a,(hl) ; Get code
inc a ; Test IN
jr z,l5f34 ; Yeap
dec a
push af
push bc
call l6148
ld hl,(l7b8b)
push hl
call l5f98
pop hl
ld (l7b8d),hl
pop de
call l6160
pop af
ld e,a
ld d,0
ld hl,l5f68
add hl,de
ld a,b
cp 3
jr z,l5f28
inc hl
inc hl
cp 9
jr z,l5f28
inc hl
inc hl
cp 8
jr z,l5f28
inc hl
inc hl
l5f28:
ld e,(hl)
inc hl
ld d,(hl)
ld a,d
or e
call ErrZ
db _IllOps
ex de,hl
jr l5f62
l5f34:
ld a,b
cp 0ah
jr nc,l5f47
cp 8
call ErrNZ
db _IllOps
ld hl,l0996
call StCALL_ ; Set CALL CHECKASSIGNMENT
ld b,0ch
l5f47:
push bc
call StPUSH ; Set PUSH HL
call l5f98
pop de
ld a,b
cp 3
call ErrNZ
db _IllOps
ld a,c
or a
jr z,l5f5f
cp d
call ErrNZ
db _InvType
l5f5f:
ld hl,l134f
l5f62:
call StCALL_ ; Set CALL <set>
ld b,0bh
ret
l5f68:
dw l12e1
dw l0688 ; Real =
dw l068d ; String =
dw l067f ; Integer =
dw l12dd
dw l069b ; Real <>
dw l06a0 ; String <>
dw l0692 ; Integer <>
dw l1300
dw l06ae ; Real >=
dw l06b3 ; String >=
dw l06a5 ; Integer >=
dw l12fc
dw l06c2 ; Real <=
dw l06c7 ; String <=
dw l06b8 ; Integer <=
dw l0000
dw l06d6 ; Real >
dw l06db ; String >
dw l06cc ; Integer >
dw l0000
dw l06e9 ; Real <
dw l06ee ; String <
dw l06e0 ; Integer <
l5f98:
call l6054
l5f9b:
push bc
call FndTabStr ; Find operator
db 1
dw l7619
pop bc
ret nz ; Nope
ld a,b
cp 4
call ErrZ
db _IllOps
ld a,(hl) ; Get operator
push af
push bc
call l6148
call l6054
pop de
pop af ; Get back operator
push af
or a ; Test +
jr nz,l5fc9 ; Nope
ld a,b
cp 0ch
jr nz,l5fc9
call StImm ; Set sequence
db a_L29
s_I29:
LD H,L
LD L,1
PUSH HL
a_L29 equ $-s_I29
ld b,8
l5fc9:
call l6160
pop af ; Get back operator
cp 2 ; Test -
jr nc,l601b ; Nope, OR or XOR
push af
ld a,b
ld hl,l1318
ld de,l1326
cp 3
jr z,l6006
ld hl,l09e9 ; Set add reals
ld de,l09f2 ; Set subtract reals
cp 9
jr z,l6006
cp 8
jr z,l6010
cp 0ah
call ErrNZ
db _IllOps
pop af
dec a
jr z,l5ffc
call StImm ; Set ADD HL,DE
db a_L30
s_I30:
ADD HL,DE
a_L30 equ $-s_I30
jr l5f9b
l5ffc:
call StImm ; Set sequence
db a_L31
s_I31:
EX DE,HL
OR A
SBC HL,DE
a_L31 equ $-s_I31
jr l5f9b
l6006:
pop af
dec a
jr nz,l600b
ex de,hl
l600b:
call StCALL_ ; Set CALL <string>
jr l5f9b
l6010:
pop af
dec a
call ErrZ
db _IllOps
ld hl,l083d
jr l600b ; Set add two strings
l601b:
ld a,b
jr nz,l6039 ; Must be XOR
cp 0bh
jr z,l602f
cp 0ah
call ErrNZ
db _IllOps
call StImm ; Set OR
db a_L32
s_I32:
LD A,H
OR D
LD H,A
a_L32 equ $-s_I32
l602f:
call StImm ; Set OR
db a_L33
s_I33:
LD A,L
OR E
LD L,A
a_L33 equ $-s_I33
jp l5f9b
l6039:
cp 0bh
jr z,l604a
cp 0ah
call ErrNZ
db _IllOps
call StImm ; Set XOR
db a_L34
s_I34:
LD A,H
XOR D
LD H,A
a_L34 equ $-s_I34
l604a:
call StImm ; Set XOR
db a_L35
s_I35:
LD A,L
XOR E
LD L,A
a_L35 equ $-s_I35
jp l5f9b
l6054:
call l60e9
l6057:
push bc
call FndTabStr ; Find operator
db 1
dw l7600
pop bc
ret nz ; Nope
ld a,b
cp 4
call ErrZ
db _IllOps
ld a,(hl) ; Get operator
push af
push bc
call l6148
call l60e9
pop de
pop af ; Get back operator
push af
dec a ; Test /
jr nz,l6083 ; Nope
ld a,b
cp 0ah
jr nz,l6083
ld hl,l1008
call StCALL_ ; Set CALL INT_TO_FLP
ld b,9
l6083:
call l6160
pop af ; Get back operator
ld e,a
ld a,b
inc e ; Test *
dec e
jr nz,l60a9 ; Nope
ld hl,l1333
cp 3
jr z,l60a4
ld hl,l06f5 ; Set integer multiply
cp 0ah
jr z,l60a4
ld hl,l09fa ; Set real multiply
l609e:
cp 9
call ErrNZ
db _IllOps
l60a4:
call StCALL_ ; Set CALL <real>
jr l6057
l60a9:
ld hl,l09ff ; Set real division
dec e ; Test /
jr z,l609e ; Yeap
dec e ; Test AND
jr nz,l60cc ; Nope
cp 0bh
jr z,l60c3
cp 0ah
call ErrNZ
db _IllOps
call StImm ; Set AND
db a_L36
s_I36:
LD A,H
AND D
LD H,A
a_L36 equ $-s_I36
l60c3:
call StImm ; Set AND
db a_L37
s_I37:
LD A,L
AND E
LD L,A
a_L37 equ $-s_I37
jr l6057
l60cc:
cp 0ah
call ErrNZ
db _IllOps
ld hl,l070f ; Set integer DIV
dec e ; Test DIV
jr z,l60a4 ; Yeap
ld hl,l0745 ; Set integer MOD
dec e ; Test MOD
jr z,l60a4
ld hl,l074e ; Set SHL
dec e ; Test SHL
jr z,l60a4
ld hl,l0756 ; Set SHR
jr l60a4
l60e9:
call FindStr ; Find NOT
dw l7579
jr nz,l6112 ; Nope
call l6112
ld a,b
cp 0ah
jr z,l6107
cp 0bh
call ErrNZ
db _IllOps
call StImm ; Set sequence
db a_L38
s_I38:
LD A,L
XOR 1
LD L,A
a_L38 equ $-s_I38
ret
l6107:
call StImm ; Set sequence
db a_L39
s_I39:
LD A,L
CPL
LD L,A
LD A,H
CPL
LD H,A
a_L39 equ $-s_I39
ret
l6112:
ld a,(l7ba1)
push af
call GetSign
ld a,e
ld (l7ba1),a
call l621d
ld a,(l7ba1)
ld e,a
call ChkNumSign
jr z,l6143
ld a,b
cp 0ah
jr nz,l613b
call StImm ; Set sequence
db a_L40
s_I40:
LD A,L
CPL
LD L,A
LD A,H
CPL
LD H,A
INC HL
a_L40 equ $-s_I40
jr l6143
l613b:
call StImm ; Set sequence
db a_L41
s_I41:
LD A,B
XOR 80H
LD B,A
a_L41 equ $-s_I41
l6143:
pop af
ld (l7ba1),a
ret
l6148:
ld a,b
cp 0ah
jr nc,l615d
cp 4
jr z,l615d
cp 8
ret z
cp 3
ret z
call StImm ; Set sequence
db a_L42
s_I42:
PUSH BC
PUSH DE
a_L42 equ $-s_I42
l615d:
jp StPUSH ; Set PUSH HL
l6160:
ld a,d
cp 9
jr nz,l6174
ld a,b
cp 0ah
jr nz,l6187
ld hl,l1008
call StCALL_ ; Set CALL INT_TO_FLP
ld b,9
jr l6187
l6174:
cp 8
jr nz,l6187
ld a,b
cp 0ch
jr nz,l6187
call StImm ; Set sequence
db a_L43
s_I43:
LD H,L
LD L,1
PUSH HL
a_L43 equ $-s_I43
ld b,8
l6187:
ld a,b
cp 9
jr nz,l6193
call StImm ; Set EXX
db a_L44
s_I44:
EXX
a_L44 equ $-s_I44
jr l61a4
l6193:
cp 8
jr nz,l61a4
ld a,d
cp 0ch
jr nz,l61a4
ld hl,l09a2
call StCALL_ ; Set CALL CHR_TO_STRG
ld d,8
l61a4:
ld a,d
cp 0ah
jr z,l61bc
jr nc,l61ce
cp 4
jr z,l61ce
cp 9
jr c,l61d3
call StImm ; Set sequence
db a_L45
s_I45:
POP HL
POP DE
POP BC
a_L45 equ $-s_I45
jr l61d3
l61bc:
ld a,b
cp 9
jr nz,l61ce
call StPOP ; Set POP HL
ld hl,l1008
call StCALL_ ; Set CALL INT_TO_FLP
ld d,9
jr l61d3
l61ce:
call StImm ; Set POP DE
db a_L46
s_I46:
POP DE
a_L46 equ $-s_I46
l61d3:
ld a,b
cp d
call ErrNZ
db _InvType
cp 3
jr nz,l61ea
ld a,e
cp c
ret z
or a
ret z
ld a,c
ld c,e
or a
ret z
call ERROR
db _InvType
l61ea:
cp 4
ret nz
ld hl,(l7b8b)
ld a,h
or l
ret z
ld de,(l7b8d)
ld a,d
or e
ret z
sbc hl,de
ret z
call ERROR
db _InvType
l6201:
ld de,l5eeb
push de
ld de,l5f9b
push de
ld de,l6057
push de
jr l622d
l620f:
ld de,l5eeb
push de
ld de,l5f9b
push de
ld de,l6057
push de
jr l6276
l621d:
call GetLabType
jr nz,l6257
ld a,(l7ba1)
ld e,a
call NegateNum
xor a
ld (l7ba1),a
l622d:
ld a,b
cp 9
jr nz,l6249
exx
push bc
push de
push hl
ld bc,256*3+031h
l6239:
ld a,c
sub 10h
ld c,a ; Get byte
call writebyte_a_addriy ; Store it
pop hl
call writeword_hl_addriy
djnz l6239
ld b,9
ret
l6249:
cp 8
jp nz,StLD.HL ; Set LD HL,val16
ld hl,l054d
call StCALL_ ; move immediate string to stack
jp StLen
l6257:
ld bc,256*6+0
call FndLABEL
jr nz,l6271
call l573d
ex de,hl
call l5287 ; Get name
ld hl,(l7b5e) ; Get lo set limit
ld (l7b8b),hl
ld a,(l7b5c) ; Get type
ld b,a
ret
l6271:
call l67b2
jr nz,l62d2
l6276:
ld a,(l7b5c) ; Get type
cp _String
jr nc,l6285
cp _Set
jr z,l6285
cp _Ptr
jr nz,l629d
l6285:
call l66da
ld hl,(l7b5e) ; Get lo set limit
ld (l7b8b),hl
ld a,(l7b5c) ; Get type
ld b,a
cp _Set
ret nz
call l5287 ; Get name
ld a,(l7b5c) ; Get type
ld c,a
ret
l629d:
cp _Array
call ErrNZ
db _NoStruktVar
call l678b
ld hl,(l7b5e) ; Get lo set limit
ld a,(hl)
cp 0ch
call ErrNZ
db _NoStruktVar
ld hl,(l7b60) ; Get hi set limit
ld a,(hl)
cp 0ah
call ErrNZ
db _NoStruktVar
ld hl,(l7b62) ; Get length of type
ld a,h
or a
call ErrNZ
db _NoStruktVar
ld h,l
ld l,6
call writeword_hl_addriy
ld hl,l0638
call StCALL_ ; Set set to stack
ld b,8
ret
l62d2:
call l6ee0
jr nz,l631c
ld hl,l0581
call StCALL_ ; Initialize a set on stack
call l6ef7 ; Test ]
ld bc,3*256+0 ;l0300
ret z ; Yeap
l62e4:
push bc
call l5ebb
ld a,b
pop bc
inc c
dec c
jr nz,l62ef
ld c,a
l62ef:
cp c
call ErrNZ
db _InvType
push bc
call FindStr ; Find ..
dw l7580
ld hl,l0591
jr nz,l6310 ; Nope, init one set element
call StPUSH ; Set PUSH HL
call l5ebb
ld a,b
pop bc
push bc
cp c
call ErrNZ
db _InvType
ld hl,l059b ; Init a contiguous set value
l6310:
call StCALL_ ; Set CALL <set>
pop bc
call l6f13 ; Test ,
jr z,l62e4 ; Yeap
jp l6f38 ; Verify ]
l631c:
call l6f1b ; Test (
jr nz,l6327 ; Nope
call l5ee8
jp l6f6e ; Verify )
l6327:
call FndTabStr ; Find function
db 2
dw l77b1
jr nz,l6335 ; Nope
ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
xor a
jp (hl)
l6335:
call FindStr ; Find NIL
dw l757c
jr nz,l6345 ; Nope
ld hl,l0000
call StLD.HL ; Set LD HL,val16
jp l642e
l6345:
;jr $
ld bc,256*3+0
call FndLABEL ; Find label with type in reg B
call ErrNZ
db _Undef ;TODO fix bb:=(Txt in [Txt]);
ld d,(hl)
dec hl
ld e,(hl)
ld a,(de)
cp 0ah
call ErrCY
db _SimTyp
push af
call l65ef
pop af
ld b,a
ret
;
; Function SQR(Num)
;
l6360:
call l65e7
ld hl,l06f3 ; Set integer SQR
ld a,b
cp 0ah
jr z,l636e
ld hl,l09f7 ; Set real SQR
l636e:
jp StCALL_ ; Set CALL <real>
;
; Function ABS(Num)
;
l6371:
call l65e7
ld a,b
cp 0ah
jr z,l6380
call StImm ; Set RES 7,B
db a_L47
s_I47:
RES 7,B
a_L47 equ $-s_I47
ret
l6380:
ld hl,l0780 ; Set integer ABS
jr l63cf
;
; Function SQRT(Num)
;
l6385:
ld hl,l0c46
jr l63ab
;
; Function SIN(Num)
;
l638a:
ld hl,l0c87
jr l63ab
;
; Function COS(Num)
;
l638f:
ld hl,l0c7f
jr l63ab
;
; Function ARCTAN(Num)
;
l6394:
ld hl,l0e46
jr l63ab
;
; Function LN(Num)
;
l6399:
ld hl,l0d2b
jr l63ab
;
; Function EXP(Num)
;
l639e:
ld hl,l0db6
jr l63ab
;
; Function INT(Num)
;
l63a3:
ld hl,l0bfd
jr l63ab
;
; Function FRAC(Num)
;
l63a8:
ld hl,l0c34
l63ab:
push hl
call l65e7
ld hl,l1008
ld a,b
cp 0ah
call z,StCALL_ ; Set CALL INT_TO_FLP
pop hl
ld b,9
jp StCALL_ ; Set CALL <real>
;
; Function TRUNC(Num)
;
l63be:
ld hl,l0fde
jr l63c6
;
; Function ROUND(Num)
;
l63c3:
ld hl,l0fd0
l63c6:
push hl
call l65e7
pop hl
ld a,b
cp 0ah
ret z
l63cf:
ld b,0ah
jp StCALL_ ; Set CALL <real>
;
; Function SUCC(Num)
;
l63d4:
ld a,_INC.HL ; INC HL
db skip.3
;
; Function PRED(Num)
;
l63d7:
ld a,_DEC.HL ; DEC HL
push af
call l65ef
pop af ; Get byte back
jp writebyte_a_addriy ; Store it
;
; Function LO(Integer)
;
l63e1:
call l65de
call StImm ; Set LD H,0
db a_L48
s_I48:
LD H,0
a_L48 equ $-s_I48
ret
;
; Function HI(Integer)
;
l63eb:
call l65de
call StImm ; Set sequence
db a_L49
s_I49:
LD L,H
LD H,0
a_L49 equ $-s_I49
ret
;
; Function SWAP(Num)
;
l63f6:
call l65de
call StImm ; Set sequence
db a_L50
s_I50:
LD A,L
LD L,H
LD H,A
a_L50 equ $-s_I50
ret
;
; Function ODD(Num)
;
l6401:
call l65de
ld hl,l078b ; Set function ODD
l6407:
ld b,0bh
l6409:
jp StCALL_ ; Set CALL ODD
;
; Function KEYPRESSED
;
l640c:
ld hl,l00a0
jr l6407
;
; Function ORD(Var)
;
l6411:
call l6f66 ; Verify (
call l5ee8
call l6f6e ; Verify )
ld a,b
cp 4
jr z,l6422
call l5ebe
l6422:
ld b,0ah
ret
;
; Function CHR(Num)
;
l6425:
call l65de
ld b,0ch
ret
;
; Function PTR(Integer)
;
l642b:
call l65de
l642e:
ld hl,l0000
ld (l7b8b),hl
ld b,4
ret
;
; Function UPCASE(Char)
;
l6437:
call l65ef
ld b,0ch
ld hl,l1fe4
jr l6409
;
; Function LENGTH(String)
;
l6441:
call l6f66 ; Verify (
ld hl,l08a3 ; Set LENGTH
l6447:
push hl
call l5ed0
call l6f6e ; Verify )
pop hl
jp l63cf
;
; Function POS(String,String)
;
l6452:
call l6f66 ; Verify (
call l5ed0
call l6f5e ; Verify ,
ld hl,l08b2
jr l6447 ; Set POS
;
; Function COPY(String,Integer,Integer)
;
l6460:
call l6f66 ; Verify (
call l5ed0
call l6f5e ; Verify ,
call l5e97
call l6f5e ; Verify ,
call StPUSH ; Set PUSH HL
call l5e97
call l6f6e ; Verify )
ld hl,l086b
call StCALL_ ; Set CALL COPY
l647e:
ld b,8
ret
;
; Function CONCAT(String,String,...)
;
l6481:
call l6f66 ; Verify (
call l5ed0
l6487:
call l6f13 ; Test ,
jr nz,l6497 ; Nope
call l5ed0
ld hl,l083d
call StCALL_ ; Set add two strings
jr l6487
l6497:
call l6f6e ; Verify )
jr l647e
;
; Function PARAMCOUNT
;
l649c:
ld hl,l1f9b
jr l64bf
;
; Function PARAMSTR(Integer)
;
l64a1:
call l65de
ld hl,l1f7d
ld b,8
jp StCALL_ ; Set CALL PARAMSTR
;
; Function RANDOM(Integer)
;
l64ac:
call l6f1b ; Test (
ld hl,l0fb4
ld b,9
jr nz,l64c1 ; Nope
call l5e97
call l6f6e ; Verify )
ld hl,l073b ; Set integer random
l64bf:
ld b,0ah
l64c1:
jp StCALL_ ; Set CALL RANDOM
;
; Function IORESULT
;
l64c4:
ld hl,l1ff1
jr l64bf
;
; Function EOF(FileVar)
;
l64c9:
call l65f7
ld hl,l6615
call l59e9
l64d2:
ld b,0bh
ret
;
; Function SEEKEOF(FileVar)
;
l64d5:
ld hl,l17e1
jr l64e2
;
; Function SEEKEOLN(FileVar)
;
l64da:
ld hl,l17d7
jr l64e2
;
; Function EOLN(TextFileVar)
;
l64df:
ld hl,l17dc
l64e2:
push hl
call l65f7
cp 6
call ErrNZ
db _MustTextFile
pop hl
call StCALL_ ; Set CALL <eoln>
jr l64d2
;
; Function FILEPOS(FileVar)
;
l64f2:
ld hl,l1a55
ld de,l1a55
jr l6500
;
; Function FILESIZE(FileVar)
;
l64fa:
ld hl,l1a5d
ld de,l1a5d
l6500:
push hl
push de
call l65f7
pop de
pop hl
cp 6
call ErrZ
db _IllTxtFile
cp 5
jr z,l64bf
ex de,hl
jr l64bf
;
; Function MEMAVAIL
;
l6514:
ld hl,l1e3d
jr l64bf
;
; Function MAXAVAIL
;
l6519:
ld hl,l1e44
jr l64bf
;
; Procedure BIOS(Integer,Integer)
; Function BIOSHL(Integer,Integer)
;
l651e:
db skip
;
; Function BIOS(Integer,Integer)
;
l651f:
xor a
push af
call l6f66 ; Verify (
call l5e97
call StPUSH ; Set PUSH HL
call l6f13 ; Test ,
jr nz,l6538 ; Nope
call l5e97
call StImm ; Set sequence
db a_L51
s_I51:
LD B,H
LD C,L
a_L51 equ $-s_I51
l6538:
call StImm ; Set POP DE
db a_L52
s_I52:
POP DE
a_L52 equ $-s_I52
ld hl,l1fea
l6540:
call l6f6e ; Verify )
call StCALL_ ; Set CALL BIOS
pop af
ld b,0ah
or a
ret nz
call StImm ; Set sequence
db a_L53
s_I53:
LD L,A
LD H,0
a_L53 equ $-s_I53
ret
;
; Procedure BDOS(Integer,Integer)
; Function BDOSHL(Integer,Integer)
;
l6553:
db skip
;
; Function BDOS(Integer,Integer)
;
l6554:
xor a
push af
call l6f66 ; Verify (
call l5e97
call StPUSH ; Set PUSH HL
call l6f13 ; Test ,
jr nz,l656c ; Nope
call l5e97
call StImm ; Set EX DE,HL
db a_L54
s_I54:
EX DE,HL
a_L54 equ $-s_I54
l656c:
call StImm ; Set POP BC
db a_L55
s_I55:
POP BC
a_L55 equ $-s_I55
ld hl,BDOS
jr l6540
;
; Function ADDR(Var)
;
l6576:
call l6f66 ; Verify (
ld bc,256*5+0
call FndLABEL
jr z,l6589
ld bc,256*6+0
call FndLABEL
jr nz,l6594
l6589:
dec hl
dec hl
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
l658f:
call StLD.HL ; Set LD HL,val16
jr l6597
l6594:
call l677f
l6597:
call l6f6e ; Verify )
ld b,0ah
ret
;
; Function SIZEOF(Var)
;
l659d:
call l6f66 ; Verify (
ld bc,256*3+0
call FndLABEL
jr nz,l65b1
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
call l5287 ; Get name
jr l65ba
l65b1:
push iy
call l677f
pop hl
call ChkChn ; Check chaining
l65ba:
ld hl,(l7b62) ; Get length of type
jr l658f
;
; Function PORT(Integer)
;
l65bf:
call l65d5
call StImm ; Set sequence
db a_L56
s_I56:
LD C,L
IN L,(C)
a_L56 equ $-s_I56
ret
;
; Function STACKPTR
;
l65ca:
call StImm ; Set sequence
db a_L57
s_I57:
LD HL,0
ADD HL,SP
a_L57 equ $-s_I57
ld b,0ah
ret
l65d5:
call l6f30 ; Verify [
call l5e97
jp l6f38 ; Verify ]
l65de:
call l6f66 ; Verify (
call l5e97
l65e4:
jp l6f6e ; Verify )
l65e7:
call l6f66 ; Verify (
call l5ea2
jr l65e4
l65ef:
call l6f66 ; Verify (
call l5ebb
jr l65e4
l65f7:
call l6f1b ; Test (
jr z,l6608 ; Yeap
ld hl,l00c2
call StLD.HL ; Set LD HL,val16
ld a,_TxtF
ld (l7b5c),a ; Set TEXT
ret
l6608:
call l5a17
call ErrNZ
db _FileVarExp
push af
call l6f6e ; Verify )
pop af
ret
l6615: ;eof procedures
dw l1a49 ; Record file
dw l17e6 ; Text file
dw l1a49 ; Untyped file
;ld c,c
;ld a,(de)
;and 17h
;ld c,c
;ld a,(de)
;
;
;
l661b:
ld a,(Envir1)
ld c,a
ld hl,(l7b58) ; Get value
ld a,(l7b5c) ; Get type
cp _Set
jr nz,l6634
call l6734
ld hl,l0623
ld de,l0612
jr l6648 ; Assign set variable
l6634:
cp _String
jr nz,l665e
ld a,(l7b62) ; Get length of type
dec a
ld h,a
ld l,6
call writeword_hl_addriy
ld hl,l0601 ; Assign string from stack
ld de,l05e2 ; Assign string from stack
l6648:
dec c
jr z,l665b
ex de,hl
l664c:
ld a,_LD.HL
inc c
jr z,l6653
ld a,_LD_a_HL
l6653:
push hl
ld hl,(l7b58) ; Get value
call StCode
pop hl
l665b:
jp StCALL_ ; Set CALL <call>
l665e:
cp _Real
jr nz,l6672
call StImm ; Set EXX
db a_L58
s_I58:
EXX
a_L58 equ $-s_I58
ld hl,l05d1 ; Save real number
dec c
jr nz,l664c
call StPOP ; Set POP HL
jr l665b
l6672:
cp _Ptr
jr z,l669d
ld a,(l7b9e) ; Get local options
bit _Ropt,a ; Test $R+
jr z,l669d ; Nope
ld hl,(l7b5e) ; Get lo set limit
ld de,(l7b60) ; Get hi set limit
inc de
or a
sbc hl,de
add hl,de
jr z,l669d
dec de
call StLD.DE ; Set LD DE,val16
ex de,hl
or a
sbc hl,de
inc hl
call StLD.BC
ld hl,l0656
call StCALL_ ; Index check on compiler directive {$R+}
l669d:
dec c
jr nz,l66b7
call StImm ; Set sequence
db a_L59
s_I59:
EX DE,HL
POP HL
a_L59 equ $-s_I59
l66a6:
call StImm ; Set LD (HL),E
db a_L60
s_I60:
LD (HL),E
a_L60 equ $-s_I60
ld a,(l7b62) ; Get length of type
dec a
ret z
call StImm ; Set sequence
db a_L61
s_I61:
INC HL
LD (HL),D
a_L61 equ $-s_I61
ret
l66b7:
ld hl,(l7b58) ; Get value
inc c
jr nz,l66cf
ld a,(l7b62) ; Get length of type
dec a
ld a,_LDHL_a
jr nz,l66cc
call StImm ; Set LD A,L
db a_L62
s_I62:
LD A,L
a_L62 equ $-s_I62
ld a,_LDA_a
l66cc:
jp StCode
l66cf:
call StImm ; Set sequence
db a_L63
s_I63:
EX DE,HL
db _LD_a_HL
a_L63 equ $-s_I63
call writeword_hl_addriy
jr l66a6
l66da:
ld a,(l7b5c) ; Get type
cp _Integ
jr nc,l6701
cp _Ptr
jr z,l6701
push af
call l678b
pop af
ld hl,l052c ; Set load real
cp _Real
jr z,l66fe
ld hl,l053a ; move string to stack
cp _String
jr z,l66fe
call l6734
ld hl,l055d ; Push set onto stack
l66fe:
jp StCALL_ ; Set CALL <set>
l6701:
ld a,(l7bbd)
or a
jr nz,l671b
ld a,_LD_a_HL
ld hl,(l7bbe)
call StCode
ld a,(l7b62) ; Get length of type
dec a
ret nz
l6714:
call StImm ; Set LD H,0
db a_L64
s_I64:
LD H,0
a_L64 equ $-s_I64
ret
l671b:
call l678b
ld a,(l7b62) ; Get length of type
dec a
jr nz,l672b
call StImm ; Set LD L,(HL)
db a_L65
s_I65:
LD L,(HL)
a_L65 equ $-s_I65
jr l6714
l672b:
call StImm ; Set sequence
db a_L66
s_I66:
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
a_L66 equ $-s_I66
ret
l6734:
ld hl,(l7b5e) ; Get lo set limit
call l5271 ; Load name
ld hl,(l7b62) ; Get length of type
ld a,(l7b6b)
rra
rra
rra
and 1fh
ld h,a
jp StLD.BC
l6749:
call GetConst ; Get constant
jr nz,l677f
ld a,b
cp 8
call ErrNZ
db _IllConst
ld l,18h
ld h,c
call writeword_hl_addriy
ld (l7b58),iy ; Set value
ld a,_Array
ld (l7b5c),a ; Set ARRAY
ld hl,l74db+7
ld (l7b5e),hl ; Set lo set limit
ld hl,l0000
ld (l7b60),hl ; Reset hi set limit
ld l,c
ld (l7b62),hl ; Set length of type
call StConst ; Store string
ld a,_LD.HL
ld hl,(l7b58) ; Get value
jp StCode
l677f:
call l6787
ret z
call ERROR
db _Undef
l6787:
call l67b2
ret nz
l678b:
ld a,(l7bbd)
ld hl,(l7bbe)
bit 1,a
jr nz,l67a2
bit 0,a
ld a,_LD.HL
jr z,l679d
ld a,_LD_a_HL
l679d:
call StCode
jr l67b0
l67a2:
bit 0,a
jr nz,l67b0
ld a,_LD.DE
call StCode
call StImm ; Set ADD HL,DE
db a_L67
s_I67:
ADD HL,DE
a_L67 equ $-s_I67
l67b0:
xor a
ret
l67b2:
call l680c
jr z,l67d9
ld bc,256*4+0
call FndLABEL
jr nz,l67ed
call l5276
ld a,(Envir1)
or a
ld a,'!'
ld b,0
jr z,l67cf
ld a,'*'
inc b
l67cf:
ld hl,l7bbd
ld (hl),b
ld hl,(l7b58) ; Get value
ld (l7bbe),hl
l67d9:
call l683a
jr z,l67d9
call l6931
jr z,l67d9
call l6974
jr z,l67d9
call l699f
xor a
ret
l67ed:
call FindStr ; Find MEM
dw l78fa
ret nz ; Nope
call l65d5
ld a,_Integ
ld (l7b5c),a ; Set INTEGER
ld hl,l0001
ld (l7b62),hl ; Set length of type
dec l
ld (l7b5e),hl ; Set lo set limit
dec l
ld (l7b60),hl ; Set hi set limit
jp l6903
l680c:
ld a,(l7bc9)
ld b,a
l6810:
dec b
ret m
push bc
ld e,b
ld d,0
ld hl,l7bcc
add hl,de
ld a,(hl)
ld c,a
ld b,4
call FndLABEL
pop bc
jr nz,l6810
push hl
ld a,b
add a,a
ld e,a
ld d,0
ld hl,(l7bca)
add hl,de
ld (l7bbe),hl
ld hl,l7bbd
ld (hl),1
pop hl
jp l6948
l683a:
ld a,(l7b5c) ; Get type
cp _Array
ret nz
call l6ee0
ret nz
call l678b
l6847:
call StPUSH ; Set PUSH HL
call l5e84
ld hl,(l7b60) ; Get hi set limit
call l5271 ; Load name
ld a,(l7b69)
cp b
call ErrNZ
db _InvType
ld hl,(l7b6b)
ld a,h
or a
jr nz,l6874
ld a,l
cp 4
jr nc,l6888
l6867:
or a
jr z,l6893
push af
call StImm ; Set DEC HL
db a_L68
s_I68:
DEC HL
a_L68 equ $-s_I68
pop af
dec a
jr l6867
l6874:
inc a
jr nz,l6888
ld a,l
cp 0fdh
jr c,l6888
l687c:
push af
call StImm ; Set INC HL
db a_L69
s_I69:
INC HL
a_L69 equ $-s_I69
pop af
inc a
jr nz,l687c
jr l6893
l6888:
call NegateInt
call StLD.DE ; Set LD DE,val16
call StImm ; Set ADD HL,DE
db a_L70
s_I70:
ADD HL,DE
a_L70 equ $-s_I70
l6893:
ld a,(l7b9e) ; Get local options
bit _Ropt,a ; Test $R+
jr z,l68ae
ld hl,(l7b6d) ; Get last memory address
ld de,(l7b6b)
or a
sbc hl,de
inc hl
call StLD.DE ; Set LD DE,val16
ld hl,l064c
call StCALL_ ; Index check on compiler directive {$R+}
l68ae:
ld hl,(l7b5e) ; Get lo set limit
call l5287 ; Get name
ld hl,(l7b62) ; Get length of type
ld a,h
or a
jr nz,l68d8
ld a,l
dec a
jr z,l68ed
dec a
jr nz,l68c9
call StImm ; Set ADD HL,HL
db a_L71
s_I71:
ADD HL,HL
a_L71 equ $-s_I71
jr l68ed
l68c9:
cp 4
jr nz,l68d8
call StImm ; Set sequence
db a_L72
s_I72:
ADD HL,HL
LD E,L
LD D,H
ADD HL,HL
ADD HL,DE
a_L72 equ $-s_I72
jr l68ed
l68d8:
ld a,(l7b9e) ; Get local options
bit _Xopt,a ; Test $X+
jr nz,l68ea ; Yeap
call StLD.DE ; Set LD DE,val16
ld hl,l06f5 ; Set integer multiply
call StCALL_
jr l68ed
l68ea:
call l690a
l68ed:
call StImm ; Set sequence
db a_L73
s_I73:
POP DE
ADD HL,DE
a_L73 equ $-s_I73
ld a,(l7b5c) ; Get type
cp _Array
jr nz,l6900
call l6f13 ; Test ,
jp z,l6847 ; Yeap
l6900:
call l6f38 ; Verify ]
l6903:
ld a,3
ld (l7bbd),a
xor a
ret
l690a:
ld b,1
l690c:
ld a,h
or a
jr nz,l6914
ld a,l
dec a
jr z,l6927
l6914:
bit 0,l
jr z,l691c
call StPUSH ; Set PUSH HL
inc b
l691c:
call StImm ; Set ADD HL,HL
db a_L74
s_I74:
ADD HL,HL
a_L74 equ $-s_I74
srl h
rr l
jr l690c
l6927:
dec b
ret z
call StImm ; Set sequence
db a_L75
s_I75:
POP DE
ADD HL,DE
a_L75 equ $-s_I75
jr l6927
l6931:
ld a,(l7b5c) ; Get type
cp _Record
ret nz
call l6f17
ret nz
ld a,(l7b5d)
ld c,a
ld b,4
call FndLABEL
call ErrNZ
db _Undef
l6948:
call l5276
ld hl,(l7b58) ; Get value
ld a,h
or l
ret z
ld hl,l7bbd
bit 0,(hl)
jr z,l6967
push hl
call l678b
pop hl
ld (hl),2
ld hl,(l7b58) ; Get value
ld (l7bbe),hl
xor a
ret
l6967:
ld hl,(l7bbe)
ld de,(l7b58) ; Get value
add hl,de
ld (l7bbe),hl
xor a
ret
l6974:
ld a,(l7b5c) ; Get type
cp _Ptr
ret nz
call l6f27
ret nz
ld hl,l7bbd
ld a,(hl)
or a
jr nz,l6988
inc (hl)
jr l6997
l6988:
push hl
call l678b
pop hl
ld (hl),3
call StImm ; Set sequence
db a_L76
s_I76:
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
a_L76 equ $-s_I76
l6997:
ld hl,(l7b5e) ; Get lo set limit
call l5287 ; Get name
xor a
ret
l699f:
ld a,(l7b5c) ; Get type
cp _String
ret nz
call l6ee0
ret nz
call l678b
call StPUSH ; Set PUSH HL
ld hl,(l7b62) ; Get length of type
push hl
call l5e97
pop hl
ld a,(l7b9e) ; Get local options
bit _Ropt,a ; Test $R+
jr z,l69c7 ; Nope
call StLD.DE ; Set LD DE,val16
ld hl,l064c
call StCALL_ ; Index check on compiler directive {$R+}
l69c7:
call StImm ; Set sequence
db a_L77
s_I77:
POP DE
ADD HL,DE
a_L77 equ $-s_I77
call l6f38 ; Verify ]
ld a,_Char
ld (l7b5c),a ; Set CHAR
ld hl,l0001
ld (l7b62),hl ; Set length of type
dec hl
ld (l7b5e),hl ; Set lo set limit
dec l
ld (l7b60),hl ; Set hi set limit
ld a,3
ld (l7bbd),a
xor a
ret
;
; Get constant
;
_GetConst:
call GetConst ; Get constant
ret z
call ERROR
db _Undef
;
; Get integer constant
;
_GetIntC:
call _GetConst ; Get constant
ld a,b
cp 0ah ;_Integ
ret z
call ERROR
db _IntConst
;
; Get string constant
;
_GetStrC:
call _GetConst ; Get constant
ld a,b
cp 8 ;_String
ret z
cp 0ch ;_Char
call ErrNZ
db _StrgConExp
ld b,8 ;_String
ret
;
; Get constant
;
GetConst:
call GetSign
push de
call GetLabType
pop de
jr z,NegateNum
inc e
dec e
call ErrNZ
db _IntRealCexp
dec e
ret
NegateNum:
call ChkNumSign
ret z
ld a,b
cp 9 ;_Real
jr nz,NegateInt
exx
ld a,b
xor 80h
ld b,a
exx
xor a
ret
NegateInt:
ld a,h
cpl
ld h,a
ld a,l
cpl
ld l,a
inc hl
xor a
ret
GetSign:
ld e,0ffh
ld a,(ix+0)
cp '-'
jr z,l6a47
inc e
cp '+'
ret nz
inc e
l6a47:
jp NewLine ; Process line
ChkNumSign:
inc e
dec e
ret z
ld a,b
cp 0ah ;_Integ
jr z,ChkNumSign_valid
cp 9 ;_Real
jr nz,ChkNumSign_bad
ChkNumSign_valid:
dec e
ret
ChkNumSign_bad:
call ERROR
db _IntRealCexp
GetLabType:
call GetConstType ; Sample constant
ret z ; Got one
ld bc,256*2+0
call FndLABEL
ret nz
ld b,(hl)
ld a,b
dec hl
cp 0ah ;_Integ
jr c,GetLabType_noOrd
ld d,(hl)
dec hl
ld e,(hl)
ex de,hl
xor a
ret
GetLabType_noOrd:
cp 9 ;_Real
jr nz,GetLabType_noReal
push bc
ld b,(hl)
dec hl
ld c,(hl)
dec hl
ld d,(hl)
dec hl
ld e,(hl)
dec hl
ld a,(hl)
dec hl
ld l,(hl)
ld h,a
exx
pop bc
ret
GetLabType_noReal:
ld c,(hl)
ld de,l7a57
push bc
inc c
GetLabType_cpyStr:
dec c
jr z,GetLabType_ex
dec hl
ld a,(hl)
ld (de),a
inc de
jr GetLabType_cpyStr
GetLabType_ex:
pop bc
ret
;
; Sample constant - Z set indicates constant
;
; Reg B holds type of constant
; Reg C holds length of constant
;
GetConstType:
ld a,(ix+0) ; Get character
cp '''' ; Test string
jr z,GetConstType_strg
cp '^' ; Test control character prefix
jr z,GetConstType_strg
cp '#' ; Test character prefix
jr nz,GetConstType_noStrg
GetConstType_strg:
ld hl,l7a57 ; Init parameter buffer
ld c,0 ; Init length
GetConstType_chkMore:
ld a,(ix+0)
cp '^' ; Test control character prefix
jr z,GetConstType_ctrChr
cp '#' ; Test character prefix
jr z,GetConstType_chrPrfx
cp '''' ; Test string
jr nz,GetConstType_ex
GetConstType_cpyStrg:
inc ix
ld a,(ix+0) ;Get character
or a
call ErrZ
db _StrConLong
cp ''''
jr nz,GetConstType_unp
inc ix
ld a,(ix+0) ;Get character
cp ''''
jr nz,GetConstType_chkMore
GetConstType_unp:
ld (hl),a
inc hl
inc c
jr GetConstType_cpyStrg
GetConstType_ctrChr:
inc ix
ld a,(ix+0) ;Get character
call doupcase ; Convert to upper case
or a
call ErrZ
db _StrConLong
xor '@'
inc ix
GetConstType_sav:
ld (hl),a
inc hl
inc c
jr GetConstType_chkMore
GetConstType_chrPrfx:
inc ix
push bc
push hl
call cnv_int ; Convert ASCII to integer
ld a,l
pop hl
pop bc
call ErrCY
db _IntegErr
jr GetConstType_sav
GetConstType_ex:
ld b,8 ;_String
ld a,c ; Get count
dec a ; Test character
jr nz,GetConstType_getLine ; .. nope
ld h,a ; .. clear HI
ld a,(l7a57) ; .. get LO
ld l,a
ld b,0ch ;_Char ; Change mode
GetConstType_getLine:
jp GetLine ; Process line
GetConstType_noStrg:
cp '$'
jr z,GetConstType_hex
call IsItDigit ; Test digit
jr nc,GetConstType_numb
xor a
dec a
ret
GetConstType_numb:
push ix
pop de
GetConstType_wtNoNum:
inc de
ld a,(de)
call IsItDigit ; Test digit
jr nc,GetConstType_wtNoNum
call doupcase ; Convert to upper case
cp 'E'
jr z,GetConstType_real
cp '.'
jr nz,GetConstType_hex
inc de
ld a,(de)
cp '.'
jr z,GetConstType_hex
cp ')'
jr z,GetConstType_hex
GetConstType_real:
call cnv_flp ; Convert to real
call ErrCY ; Real constant error
db _RealErr
exx ; Real into alternate set
ld b,9 ;_Real ; .. set mode
jr GetConstType_getLine
GetConstType_hex:
call cnv_int ; Convert ASCII to integer
call ErrCY
db _IntegErr
ld b,0ah
jr GetConstType_getLine
;
; Transfer immediate opcodes
; Sequence starts with length
;
StImm:
ex (sp),hl
push bc
ld b,(hl) ; Get length
inc hl
StI_loop:
ld a,(hl) ; Get byte
call writebyte_a_addriy ; Store it
inc hl
djnz StI_loop
pop bc
ex (sp),hl
ret
StLen:
ld a,c ; Get byte
call writebyte_a_addriy ; Store it
;
; Store string
;
StConst:
ld hl,l7a57
inc c
StC_loop:
dec c
ret z
ld a,(hl) ; Get character
inc hl
call writebyte_a_addriy ; Store it
jr StC_loop
;
; Set PUSH HL
;
StPUSH:
ld a,_PUSH.HL
jr writebyte_a_addriy
;
; Set POP HL
;
StPOP:
ld a,_POP.HL
jr writebyte_a_addriy
;
; Set JP
;
StJP:
ld a,_JP
jr writebyte_a_addriy
;
; Insert operand
; ENTRY Reg DE holds operand
; (Set word in reg DE)
;
writeword_de_addriy:
ld a,e
call writebyte_a_addriy
ld a,d
jr writebyte_a_addriy
;
; Set JP WORD
;
StJP_:
ld a,_JP
jr StCode
;
; Set CALL WORD
;
StCALL_:
ld a,_CALL
jr StCode
;
; Set LD BC,WORD
;
StLD.BC:
ld a,_LD.BC
jr StCode
;
; Set LD DE,WORD
;
StLD.DE:
ld a,_LD.DE
jr StCode
;
; Set LD HL,WORD
;
StLD.HL:
ld a,_LD.HL
;
; Insert opcodes in Accu, reg L and reg H
;
StCode:
call writebyte_a_addriy
;
; Insert word in reg HL
;
writeword_hl_addriy:
ld a,l
call writebyte_a_addriy
ld a,h
;
; Insert byte in Accu
;
writebyte_a_addriy:
push bc
ld b,a
ld a,(CmpTyp) ; Get compile flag
or a ; Test mode
jr nz,St__noSt ; Searching or compiling
ld (iy+0),b ; Store byte into memory
St__noSt:
inc iy ; Update PC
or a ; Test compile to memory
jr z,St__skp ; Yeap
push hl
push de
dec a ; Test search
jr z,St__St ; Nope ; .. compile to file
push iy
pop de
dec de
ld hl,(l00ce) ; Get current PC
or a
sbc hl,de
call ErrZ
db _FndRTerr
jr St__pop
St__St:
call savebyte_b ; Put byte to file
St__pop:
pop de
pop hl
St__skp:
pop bc
;
; Check enough memory
;
ChkOvfl:
push hl
push de
push iy
pop de
ld a,(CmpTyp) ; Get compile flag
or a
jr z,ChkOv.mem ; Skip if compiling to memory
ld de,(MemsTop) ; Get memory top
dec a
jr nz,ChkOv.mem
ld de,(COMsTop) ; Get top of .COM file
ld a,(IncFlg) ; Test memory read
or a
jr z,ChkOv.mem ; Yeap
ld de,(INCsTop)
ChkOv.mem:
ld hl,(LabPtr) ; Get label pointer
scf
sbc hl,de
call ErrCY
db _CompOvfl
push iy
pop de
ld hl,(DataBeg) ; Get start of data
dec h
dec h
sbc hl,de
call ErrCY
db _MemOvfl
pop de
pop hl
ret
;
; Put byte in reg B to file
;
savebyte_b:
ld hl,RRN_stat ; Point to file access
set 1,(hl) ; Set write enabled
bit 0,(hl) ; Test re-read
jr z,SkpRdRRN ; Nope
res 0,(hl) ; Clear it
push bc
call readrecord_TmpBuff ; Re-read record
pop bc
SkpRdRRN:
ld a,(RecPtr) ; Get record pointer
ld e,a
ld d,0
ld hl,TmpBuff
add hl,de ; Build buffer address
ld (hl),b ; Store byte
inc a ; Advance record pointer
jp p,StToF__ex ; Still within limits
call writerecord_TmpBuff ; Write record
ld hl,(FFCB+_rrn)
inc hl ; Advance record count
ld (FFCB+_rrn),hl
xor a
StToF__ex:
ld (RecPtr),a ; Set record pointer
ret
;
; Allocate space in reg DE
;
VarAlloc:
ld hl,(DataBeg) ; Get start of data
or a
sbc hl,de
call ErrCY
db _MemOvfl
ld (DataBeg),hl ; Set start of data
jr ChkOvfl ; Check enough memory
;
; Store back current PC to ^HL
;
storeback_iy_to_addrhl:
push iy ; Get PC
pop de
;
; Store back reg DE to ^HL
;
storeback_de_to_addrhl:
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to memory
jr z,StBackMem ; nope
push iy
push hl
pop iy
call writeword_de_addriy ; Set word
pop iy
ret
flushunfinished
ld a,(RecPtr) ; Get record pointer
or a
ret z
push bc
push de
push hl
;ld a,h
;and l
;inc a ;-1=fake record number
;jr z,flushunfinished_skip
call flushunfinishedpp
;flushunfinished_skip
;close, open to force flush???
;ld de,FFCB
;ld c,_close
;call _BDOS ; BDOS with keep ix,iy
;ld de,FFCB
;ld c,_open
;call _BDOS ; BDOS with keep ix,iy
pop hl
pop de
pop bc
ret
StBackMem:
call flushunfinished
push bc
push de
push hl
ld hl,(MemsTop) ; Get memory top
ld a,(BackLevel) ; Get back fix level
ld b,a
inc b
l6c5e:
dec b
jr z,l6c84
ld e,(hl)
inc hl
ld d,(hl)
ex (sp),hl
or a
sbc hl,de
add hl,de
ex (sp),hl
jr c,l6c71
inc hl
inc hl
inc hl
jr l6c5e
l6c71:
dec hl
ex de,hl
ld l,b
ld h,0
add hl,hl
add hl,hl
ld b,h
ld c,l
add hl,de
ld d,h
ld e,l
dec hl
inc de
inc de
inc de
lddr
inc hl
l6c84:
pop de
ld (hl),e
inc hl
ld (hl),d
inc hl
pop de
ld (hl),e
inc hl
ld (hl),d
pop bc
ld hl,BackLevel ; Point to back fix level
inc (hl)
ret nz
xor a
jr ForceBack
;
; Fix back level
;
FixBack:
ld a,(BackLevel) ; Get back fix level
or a
ret z
ForceBack:
push bc
push de
push iy
ld b,a
ld hl,(MemsTop) ; Get memory top
Back_Loop:
push bc
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl
ex de,hl
call ChkChn ; Check chaining
pop hl
ld b,(hl)
inc hl
push hl
call savebyte_b ; Put byte to file
pop hl
ld b,(hl)
inc hl
push hl
call savebyte_b ; Put byte to file
pop hl
pop bc
djnz Back_Loop
pop hl
pop de
pop bc
;
; Check chaining
;
ChkChn:
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to memory
call z,flushunfinished ;nope
push hl
pop iy
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to memory
ret nz ; yes
push de
push bc
ld de,(CodePC) ; Get code pointer
or a
sbc hl,de
ld a,l
and 7fh
ld (RecPtr),a ; Set record pointer
add hl,hl
ld l,h
rla
and 1
ld h,a
ld de,(RRN_off) ; Get record base
add hl,de ; Calculate new record
ld de,(FFCB+_rrn)
or a
sbc hl,de
add hl,de
jr z,Chk_sameRRN
push hl
call writerecord_TmpBuff ; Write record
pop hl
ld (FFCB+_rrn),hl ; Reset record
Chk_sameRRN:
pop bc
pop de
ret
;
; Read random record from file
; Read a record
;
readrecord_TmpBuff:
;ld hl,(FFCB+_rrn)
;jr $
ld c,_rndrd ; .. load read function
jr l6d09 ; .. fall in read
;
; Write a record
;
writerecord_TmpBuff:
ld hl,RRN_stat ; Point to file access
set 0,(hl) ; Set re-read enabled
bit 1,(hl) ; Test record to be written
ret z ; Nope
res 1,(hl) ; Reset it
flushunfinishedpp
;write unfinished last sector???
ld c,_rndwr
l6d09:
push bc ; Save function
ld de,TmpBuff
ld c,_setdma
call _BDOS ; Set disk buffer
pop bc
ld de,FFCB
call _BDOS ; Read or write record
ret ;КОСТЫЛЬ!!! иначе lister не компилируется на диск (читает сектор за границей файла перед патчем и записью?)
or a
ret z
;dec a
;ret z
;cp 3
;ret z
cp 128 ;fail
ret nz ;not fail
call ERROR
db _DskFull
;
; Save environment to stack
;
SavEnv2:
exx
ld de,Envir2
jr SavEnv7
;
; Save environment to stack
;
l6d2a:
exx
ld de,Envir1
SavEnv7:
pop hl
ld (Env_PC),hl
ld hl,-l000d;lfff3
add hl,sp
ld sp,hl
ex de,hl
ld bc,l000d
ldir
BackEnv_PC:
ld hl,(Env_PC)
push hl
exx
ret
RestEnv2:
exx
ld de,Envir2
jr RestEnv7
;
; Get back environment
;
RestEnv1:
exx
ld de,Envir1
RestEnv7:
pop hl
ld (Env_PC),hl
ld hl,0;l0000
add hl,sp
ld bc,l000d
ldir
ld sp,hl
jr BackEnv_PC
;
; Restore environment from stack, leave stack intact
;
CpyEnv2:
exx
ld de,Envir2
jr CpyEnv7
l6d63:
exx
ld de,Envir1
CpyEnv7:
ld hl,2;l0002
add hl,sp
ld bc,l000d
ldir
exx
ret
;
; Store current PC into label table
;
puttolabel_i_y:
push iy
pop de
puttolabel_d_e:
ld a,d
call puttolabel
ld a,e
puttolabel:
push hl
ld hl,(LabPtr) ; Get label pointer
ld (hl),a
dec hl
ld (LabPtr),hl ; Set label pointer
pop hl
jp ChkOvfl ; Check enough memory
;
; Get label
;
GetLabel:
ld a,(ix+0) ; Get 1st character
call IsItLab ; Test label character
;
; Build label
;
SampLabel:
call ErrCY
db _IllChar
call DoubleLabel ; Verify no double label
l6d94:
call Reserved ; Verify no reserved word
ld a,(ix+0)
l6d9a:
cp 'a'
jr c,l6da4
cp 'z'+1
jr nc,l6da4
sub 'a'-'A'
l6da4:
call puttolabel
inc ix
ld a,(ix+0)
call IsItValid ; Test valid character
jr nc,l6d9a ; Yeap
ld hl,(LabPtr) ; Get label pointer
inc hl
set 7,(hl)
jp GetLine ; Process line
l6dba:
ld a,(ix+0)
call IsItLab ; Test label character
call ErrCY
db _IllChar
jr l6d94
;
; Set label pointer
;
SetLabPtr:
ld hl,(PrevLabPtr) ; Get previous label pointer
ld de,(LabPtr) ; Get label pointer
or a
sbc hl,de
ex de,hl
call puttolabel_d_e ; Put to table
ld hl,(LabPtr) ; Get label pointer
ld (PrevLabPtr),hl ; Unpack into previous
ret
l6ddb:
ld hl,(CurLab) ; Get current label pointer
jr l6de3
;
;
; Find label from table
; ENTRY Reg B holds selected TYPE
; Reg C holds item flag
; 0 if 1st item in line
; -1 if not 1st one
; EXIT Zero set if label found
;;
;; l7bc1 = 00, A = -1, NZ ---->>> Not found
;; l7bc1 = type, NZ ---->>> Not same type as B
;; Z ---->>> Same type
;; HL, DE hold pointers
;
FndItem:
ld hl,(l7b77) ; Get top of available memory
l6de3:
ld (l7b7d),hl
ld a,(FirstVAR)
cp c
jr z,l6e48
ld a,c
ld (FirstVAR),a
ld hl,(PrevLabPtr) ; Get previous label pointer
l6df3:
ld de,(l7b7d)
xor a
sbc hl,de ; Test pointer reached
add hl,de
jr nz,l6e03
xor a
ld (l7bc1),a
dec a
ret
l6e03:
inc hl
ld e,(hl) ; Get length of entry ?????????
inc hl
ld d,(hl)
add hl,de ; Point to end
ld a,(hl) ; Test more
or a
jr z,l6df3 ; .. end of table ??????????????
dec hl
ld a,(hl) ; Get type
inc hl
cp c
jr nz,l6df3 ; .. not what we expect
push ix
pop de ; Copy pointer
push bc
push hl
dec hl ; Fix to lable
dec hl
l6e19:
ld b,(hl) ; Get characters
ld a,(de)
dec hl
inc de
ld c,b ; Save label
res 7,b ; Clear MSB
cp 'a' ; Check a..z
jr c,l6e2a
cp 'z'+1
jr nc,l6e2a
sub 'a'-'A' ; .. map to a..z
l6e2a:
cp b ; Compare
jr nz,l6e37
bit 7,c ; Test last character
jr z,l6e19 ; .. nope
ld a,(de) ; Verify end of label
call IsItValid ; Test valid character
jr c,l6e3b ; Nope
l6e37:
pop hl
pop bc
jr l6df3
l6e3b:
ld (l7bc2),hl ; Save pointers
ld (l7bc4),de
pop hl
pop bc
ld a,(hl) ; Save type
ld (l7bc1),a
l6e48:
ld hl,(l7bc2)
ld de,(l7bc4)
ld a,(l7bc1)
cp b ; Fix result
ret
;
; Get TYPE from table
; ENTRY Reg B holds TYPE searched for
; Reg C holds flag ???????
; EXIT Zero set if TYPE found
; Reg HL points to TYPE
; (Find label with type in reg B)
;
FndLABEL:
call FndItem ; Find it
ret nz ; .. nope
jr SetLine ; .. set source pointer
;
; Find string
; ENTRY <SP> points to length of code
; followed by address of string
; EXIT Zero flag set indicates found
; (Find constant string list ^PC)
; Z set says found
;
FndTabStr:
ex (sp),hl
ld c,(hl) ; Get length of data following string
inc hl
ld e,(hl) ; Get address of string
inc hl
ld d,(hl)
inc hl
ex (sp),hl
ex de,hl
FndDirStr:
call FndStr ; Find string
ret z ; Got it
dec hl ; Postion to previous character
FndDirStr_fix:
bit _MB,(hl) ; Find end of string
inc hl
jr z,FndDirStr_fix
ld b,0
add hl,bc ; Position to next string in list
ld a,(hl)
or a ; Test more in list
jr nz,FndDirStr ; Yeap
dec a ; Set string not found
ret
;
; Find constant string ^PC
; Z set says found
;
FindStr:
ex (sp),hl
ld e,(hl) ; Get address of string
inc hl
ld d,(hl)
inc hl
ex (sp),hl
ex de,hl
;
; Find string ^HL
;
FndStr:
push ix ; Copy source pointer
pop de
ld a,(hl) ; Get character from searched string
call IsItLab ; Test label character
jr c,l6e92 ; Nope
call l6e9c ; Compare
ret nz ; Not found
ld a,(de) ; Get character from source
call IsItValid ; Test valid character
jr c,SetLine ; Nope
or a
ret
l6e92:
call l6e9c ; Compare
ret nz ; Not found
SetLine:
push de ; Set resulting source pointer
pop ix
jp GetLine ; Process line
;
; Compare reference ^HL: source ^DE
; Z set says match
;
l6e9c:
push bc
l6e9d:
ld b,(hl) ; Get from reference
ld a,(de) ; Get from source
inc hl
inc de
ld c,b ; Save reference
res _MB,b ; Strip off MSB
cp 'a' ; Test range
jr c,l6eae
cp 'z'+1
jr nc,l6eae
sub 'a'-'A' ; Convert to UPPER case
l6eae:
cp b ; Compare
jr nz,l6eb6 ; No match
bit _MB,c ; Test end of reference
jr z,l6e9d ; Nope
xor a ; Force match
l6eb6:
pop bc
ret
;
; Verify no reserved word
;
Reserved:
ld hl,l7513
l6ebb:
ld c,(hl)
inc c
ret z
dec c
inc hl
ld e,(hl)
inc hl
ld d,(hl)
inc hl
push hl
ex de,hl
call FndDirStr
pop hl
jr nz,l6ebb
call ERROR
db _ResWord
DoubleLabel:
ld a,(l7b91) ; Get ???
ld c,a
call l6ddb
ld a,(l7bc1)
or a
ret z
call ERROR
db _DoubleLab
l6ee0:
ld a,'['
call l6f29
ret z
ld a,(ix+0)
cp '('
ret nz
ld a,(ix+1)
cp '.'
ret nz
l6ef2:
inc ix
jp NewLine ; Process line
;
; Test ] - Z set says found
;
l6ef7:
ld a,']'
call l6f29
ret z
;;:::
ld a,(ix+0)
cp '.'
ret nz
ld a,(ix+1)
cp ')'
ret nz
jr l6ef2
;
; Test colon : - Z set says found
;
l6f0b:
ld a,':'
jr l6f29
;
; Test semicolon ; - Z set says found
;
l6f0f:
ld a,';'
jr l6f29
;
; Test comma , - Z set says found
;
l6f13:
ld a,','
jr l6f29
l6f17:
ld a,'.'
jr l6f29
;
; Test left parenthesis ( - Z set says found
;
l6f1b:
ld a,'('
jr l6f29
l6f1f:
ld a,')'
jr l6f29
;
; Test equate = - Z set says found
;
l6f23:
ld a,'='
jr l6f29
l6f27:
ld a,'^'
l6f29:
cp (ix+0)
ret nz
jp NewLine ; Process line
;
; Verify [
;
l6f30:
call l6ee0
ret z
call ERROR
db _LftBrExp
;
; Verify ]
;
l6f38:
call l6ef7 ; Test ]
ret z
call ERROR
db _RgtBrExp
;
; Verify :
;
l6f40:
call l6f0b ; Test :
ret z
call ERROR
db _SemiExp
;
; Verify ;
;
l6f48:
call l6f0f ; Test ;
ret z ; Yeap
l6f4c:
call ERROR
db _ColExp
l6f50:
call l6f0f ; Test ;
ret z ; Yeap
ld a,(l7b98)
or a
jr z,l6f4c
call ERROR
db _Undef
;
; Verify ,
;
l6f5e:
call l6f13 ; Test ,
ret z ; Yeap
call ERROR
db _CommaExp
;
; Verify (
;
l6f66:
call l6f1b ; Test (
ret z ; Yeap
call ERROR
db _LftPar
;
; Verify )
;
l6f6e:
call l6f1f
ret z
call ERROR
db _RgtPar
;
; Verify =
;
l6f76:
call l6f23 ; Find =
ret z
call ERROR
db _EquExp
l6f7e:
call FindStr ; Find :=
dw l7582
ret z ; Yeap
call ERROR
db _AssigExp
l6f88:
call FindStr ; Find OF
dw l7560
ret z ; Yeap
call ERROR
db _NoOF
;
; Process source line
;
NewLine:
call l7124 ; Get character from file
GetLine:
xor a
ld (l7b98),a
dec a
ld (FirstVAR),a
ld a,(ix+0) ; Get a character
or a ; Test empty
jr z,NewLine ; Yeap, so get next
cp ' ' ; Skip blanks
jr z,NewLine
cp tab ; Skip tabs
jr z,NewLine
cp '(' ; Test possible comment
jr z,l6fb5
cp '{' ; Test real comment
jr z,l6fbf
l6fb3:
xor a
ret
l6fb5:
ld a,(ix+1) ; Get next
cp '*' ; Test comment
jr nz,l6fb3 ; Nope
call l7124 ; Get next character
l6fbf:
push bc
ld b,(ix+0) ; Get comment indicator
ld a,(ix+1) ; Get next character
cp '$' ; Test compiler directive
jr z,l6feb ; Maybe
l6fca:
call l7124 ; Get next character
l6fcd:
ld a,b
cp '*' ; Test two character indicators
ld a,(ix+0)
jr nz,l6fe4 ; Nope
cp b
jr nz,l6fca
ld a,(ix+1)
cp ')'
jr nz,l6fca
call l7124 ; Get character from file
jr l6fe8
l6fe4:
cp '}' ; Test end of comment
jr nz,l6fca ; Nope, wait for
l6fe8:
pop bc
jr NewLine
l6feb:
push bc
push de
push hl
call l7124 ; Get character from file
l6ff1:
call l7124 ; Get character from file
ld a,(ix+0)
call doupcase ; Convert to upper case
cp 'I' ; Test include or I/O error
ld b,00000001b
jr z,l704d
cp 'R' ; Test index range test
ld b,00000010b
jr z,l704d
cp 'A' ; Test absolute code
ld b,00000100b
jr z,l704d
cp 'U' ; Test user break
ld b,00001000b
jr z,l704d
cp 'X' ; Test arry optimization
ld b,00010000b
jr z,l704d
cp 'V' ; Test var type test
ld b,00100000b
jr z,l704d
cp 'B' ; Test I/O mode
ld b,01000000b
jr z,l704d
cp 'C' ; Test keyboard interrupt
ld b,10000000b
jr z,l704d
cp 'W' ; Test WITH check
jr z,l707a
;
; Next directives used by MS-DOS only.
; They will be checked for compatibility only
;
ld b,00000000b
cp 'K' ; Test stack check ([$K+, $K-])
jr z,l704d
cp 'D' ; Test device check ([$D+, $D-])
jr z,l704d
cp 'F' ; Test number of open files ([$Fnum])
jr z,l708e
cp 'G' ; Test input buffer ([$Gnum])
jr z,l708e
cp 'P' ; Test output buffer ([$Pnum])
jr z,l708e
call ERROR ; Invalid directive
db _CompDirec
l7048:
pop hl
pop de
pop bc
jr l6fcd
;
; Set or reset directive $x+ or $x-
;
; Bit to be attached held in reg B
;
l704d:
call l7124 ; Get character from file
ld a,(ix+0)
ld c,0 ; Init for set
cp '+' ; Test it
jr z,l7065 ; Yeap
dec c ; Prepare for reset - all bits set
cp '-'
jr z,l7065
dec b ; Remember $I is 00000001b - used multiple
call ErrNZ ; Else error
db _CompDirec
jr l709b ; Now process include
l7065:
ld hl,l7b9d ; Point to options
ld a,(hl) ; Get current bits
xor c ; Toggle bits or let in tact
or b ; Insert bit
xor c ; Set result
ld (hl),a
l706d:
call l7124 ; Get character from file
l7070:
ld a,(ix+0)
cp ',' ; Test more
jp z,l6ff1 ; Yeap
jr l7048
l707a:
call l7124 ; Get character from file
ld a,(ix+0)
call IsItDigit ; Test digit
call ErrCY
db _CompDirec
sub '0'
ld (l7bc7),a ; Change depth for WITH
jr l706d
;
; Process MS-DOS compatible directives
;
l708e:
call l7124 ; Get character from file
ld a,(ix+0)
call IsItDigit ; Test digit
jr nc,l708e ; Yeap, skip over
jr l7070
l709b:
cp ' '
jr nz,l70a7 ; Skip over directive
call l7124 ; Get character from file
ld a,(ix+0)
jr l709b
l70a7: ;include???
ld a,(IncFlg) ; Get memory read flag
or a
call ErrNZ ; Should be memory read
db _INCLerr
push ix
pop de
call l2d2a ; Prepare .PAS file
push de
pop ix
ld de,l005c
push de
;jr $
ld c,_open
call _BDOS ; Open file ;WHERE IS CLOSE???
pop hl
inc a
call ErrZ
db _NoFileErr
ld de,l790f
ld bc,FCBlen
ldir ; Unpack file
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr z,l70e2 ; Yeap
ld hl,TmpBuff
ld (l7be4),hl ; Save top of .COM file
ld hl,l79d7 ; Get start of source line
ld a,1
jr l7103
l70e2:
ld hl,(LabPtr) ; Get label pointer
ld de,(COMsTop) ; Get top of .COM file
ld (l7be4),de ; Save it
or a
sbc hl,de ; Calculate difference
srl h
rr l
ld a,h
or a
call ErrZ ; If hi zero, no memory
db _CompOvfl
ld a,l
and RecLng
ld l,a
push hl
add hl,hl
ld a,h
pop hl
add hl,de
l7103:
ld (INCsTop),hl
ld (l7be9),hl
ld (l7be8),a
ld (IncFlg),a ; Re/Set memory read flag
ld hl,l0000
ld (l7beb),hl
ld a,(l7b9d) ; Get options
ld (l7b9f),a
ld a,(l7bc7) ; Get depth for WITH
ld (l7bc8),a
jp l7048
;
; Get character from file
;
l7124:
ld a,(ix+0)
inc ix
or a
ret nz
push bc
push de
push hl
ld a,(l7ba2) ; Get end of file
or a
call ErrNZ
db _IllSrcEnd
ld hl,(l7bd7) ; Get source pointer
ld (l7bd9),hl ; Unpack it
ld hl,(l7beb)
ld (l7bed),hl
ld hl,l79d7 ; Get start of source line
push hl
pop ix ; Copy it
ld b,RecLng-1 ; Set max length
l714a:
push hl
push bc
call l71f3
if TERM
;push af
;push ix
;push iy
;PRCHAR_
;pop iy
;pop ix
;pop af
else
;push af
;push ix
;push iy
;PRCHAR
;pop iy
;pop ix
;pop af
endif
pop bc
pop hl
cp cr
jr z,l7175
cp eof
;jr z,$ ;never
jr z,l716a
cp tab
jr z,l7161
cp ' '
jr c,l714a
l7161:
djnz l7166
inc b
jr l714a
l7166:
ld (hl),a
inc hl
jr l714a
l716a:
ld (l7ba2),a ; Set end of file
call l717e
call l718f ; Test abort
jr l7178
l7175:
call l717e ;compile_newline
l7178:
ld (hl),0
pop hl
pop de
pop bc
ret
l717e: ;compile_newline
push af
push hl
ld hl,(l7bef)
inc hl ; Advance line count
ld (l7bef),hl
ld a,l
and 0fh
;jr z,l7191
pop hl
pop af
ret
;
; Test abortion of compilation
;
l718f:
push af
push hl
l7191:
push bc
push de
push ix
push iy
ld a,cr
call puttoconsole_a ; Put to console
ld a,(IncFlg) ; Test memory read
or a
jr z,l71a6 ; Yeap
ld a,'I'
jr l71a8
l71a6:
ld a,' '
l71a8:
call puttoconsole_a ; Put to console
ld a,' '
call puttoconsole_a ; Put to console
ld hl,(l7bef) ; Get line count
call l2e61 ; Print number
call l00a0 ; Test key pressed
or a
jr z,l71ea
call l0200
db ' *** Abort compilation'
db null
call l2d01 ; Ask for YES or NO
call ErrNZ
db _ABORT
ld b,32
l71e1:
call l0200
db bs,' ',bs
db null
djnz l71e1
l71ea:
pop iy
pop ix
pop de
pop bc
pop hl
pop af
ret
;
; Read character from file
;
l71f3:
ld a,(IncFlg) ; Test memory read
or a
jr nz,l7205 ; Nope
l71f9:
ld hl,(l7bd7) ; Get source pointer
ld a,(hl)
cp eof ; Test end of file
ret z ; Yeap
inc hl
ld (l7bd7),hl
ret
l7205:
ld hl,(l7be9)
ld de,(INCsTop)
or a
sbc hl,de
add hl,de
jr c,l7242
ld de,(l7be4) ; Get top of .COM file
ld a,(l7be8)
ld b,a
l721a:
push bc
push de
ld c,_setdma
call _BDOS ; Set disk buffer
ld de,l790f
ld c,_rdseq
call _BDOS ; Read record
pop de
pop bc
;or a
;jr nz,l7237
xor 128 ;EOF in NedoOS
jr z,l7237
;ld hl,RecLng
ld l,a
ld h,0
;CP/M has eofs in the end of last sector?
;do this by hand:
xor 128
jr z,readchar_load_noaddzeros ;full sector
;a=128+bytes loaded
neg
;a=128-bytes loaded
push bc
push de
ld b,a
ld a,e
add a,127
ld e,a
adc a,d
sub e
ld d,a
;de= Point to buffer end
ld a,eof;-1
ld (de),a
dec de
djnz $-2
pop de
pop bc
readchar_load_noaddzeros
add hl,de ; Advance buffer
ex de,hl
djnz l721a
jr l723f
l7237:
ld a,eof ; Set end of file
ld (de),a
inc de
ld (INCsTop),de
l723f:
ld hl,(l7be4) ; Get top of .COM file
l7242:
ld a,(hl)
inc hl
ld (l7be9),hl
cp eof
jr nz,l725d
ld c,_close
call BDOS_with_FCB1
xor a
ld (IncFlg),a ; Enable memory read
ld a,(l7b9f)
ld (l7b9d),a ; Reset options
ld a,(l7bc8)
ld (l7bc7),a ; Set depth for WITH
jp l71f9
l725d:
ld hl,(l7beb)
inc hl
ld (l7beb),hl
ret
;
; Perform OS call
;
_BDOS:
push ix ; Preserve index registers
push iy
call BDOS ; Call system
pop iy
pop ix
ret
;
; Test label character
; C set says no
;
IsItLab:
cp 'A'
ret c
cp 'Z'+1
ccf
ret nc
cp '_'
ret z
cp 'a'
ret c
cp 'z'+1
ccf
ret
;
; Test valid character
; C set says no
;
IsItValid:
call IsItLab ; Test label character
ret nc ; Yeap
;
; Test character a digit
; C set says no
;
IsItDigit:
cp '0' ; Test digit
ret c
cp '9'+1
ccf
ret
;
; Compare signed integers HL:DE
;
; C set if HL<DE
; Z set if HL=DE
;
l728d:
ld a,h
xor d
ld a,h
jp m,l7298
cp d
ret nz
ld a,l
cp e
ret
l7298:
rla
ret
;
; HL:=HL*DE - C set on overflow
;
l729a:
ld b,h
ld c,l
ld hl,0 ; Init product
ld a,16
l72a1:
add hl,hl
ret c
ex de,hl
add hl,hl
ex de,hl
jr nc,l72aa
add hl,bc
ret c
l72aa:
dec a
jr nz,l72a1
ret
;
; HL:=HL DIV DE *** NOT USED HERE
; HL:=HL MOD DE
;
ld b,d
ld c,e
ex de,hl
xor a
ld h,a
ld l,a
ld a,17
l72b6:
adc hl,hl
sbc hl,bc
jr nc,l72be
add hl,bc
scf
l72be:
ccf
rl e
rl d
dec a
jr nz,l72b6
ex de,hl
ret
;
; Process error if entry C
;
ErrCY:
ex (sp),hl
inc hl ; Fix caller's address
ex (sp),hl
ret nc ; No error
jr l72de
l72ce:: ;;**
ex (sp),hl
inc hl ; Fix caller's address
ex (sp),hl
ret c ; No error
jr l72de
;
; Process error if entry Z
;
ErrZ:
ex (sp),hl
inc hl ; Fix caller's address
ex (sp),hl
ret nz ; No error
jr l72de
;
; Process error if entry NZ
;
ErrNZ:
ex (sp),hl
inc hl ; Fix caller's address
ex (sp),hl
ret z ; No error
;
; Common entry of error routine
;
l72de:
pop hl ; Get back caller
dec hl ; Fix pointer
push hl
;
; Process error
;
ERROR:
pop hl ; Get pointer
ld a,(hl) ; Fetch error number
l72e3:
call l718f ; Test abort
ld (l7901),a
or a
jr z,l730c
push ix
pop hl
ld de,l79d7 ; Get start of source line
sbc hl,de
ld de,(l7bed)
ld a,(IncFlg) ; Test memory read
or a
jr nz,l7308 ; Nope
ld de,(l4544) ; Get start of text
sbc hl,de
ld de,(l7bd9) ; Get back source pointer
l7308:
add hl,de
ld (l790c),hl ; Save current editor address
l730c:
ld a,(CmpTyp) ; Get compile flag
dec a ; Test compiling to file
jr nz,l731a ; Nope
ld de,FFCB
ld c,_close
call _BDOS ; Close file
l731a:
ld sp,(l7b71) ; Get back stack
ret ; Exit compiler
;
; Compiler tables
; Internal label table
;
; -->> INTEGER
;
l731f:
dw _.INT
ssINT:
dw l74d3+7
db 'R'+MSB,'EGETNI'
db 0,_Type
_.INT equ $-ssINT
;
; -->> CHAR
;
dw _.CHAR
ssCHAR:
dw l74db+7
db 'R'+MSB,'AHC'
db 0,_Type
_.CHAR equ $-ssCHAR
;
; -->> REAL
;
dw _.REAL
ssREAL:
dw l74e3+7
db 'L'+MSB,'AER'
db 0,_Type
_.REAL equ $-ssREAL
;
; -->> BOOLEAN
;
dw _.BOOL
ssBOOL:
dw l74eb+7
db 'N'+MSB,'AELOOB'
db 0,_Type
_.BOOL equ $-ssBOOL
;
; -->> TEXT
;
dw _.TEXT
ssTEXT:
dw l74f3+7 ;text file type???
db 'T'+MSB,'XET'
db 0,_Type
_.TEXT equ $-ssTEXT
;
; -->> BYTE
;
dw _.BYTE
ssBYTE:
dw l74fb+7 ;byte type
db 'E'+MSB,'TYB'
db 0,_Type
_.BYTE equ $-ssBYTE
;
; -->> TRUE
;
dw _.TRUE
ssTRUE:
dw _TRUE
db _Bool
db 'E'+MSB,'URT'
db 0,_Const
_.TRUE equ $-ssTRUE
;
; -->> FALSE
;
dw _.FALSE
ssFALSE:
dw FALSE
db _Bool
db 'E'+MSB,'SLAF'
db 0,_Const
_.FALSE equ $-ssFALSE
;
; -->> MAXINT
;
dw _.MXINT
ssMAXINT:
dw MAXINT
db _Integ
db 'T'+MSB,'NIXAM'
db 0,_Const
_.MXINT equ $-ssMAXINT
;
; -->> PI
;
dw _.PI
ssPI:
db 082h,021h,0a2h,0dah,00fh,049h
db _Real
db 'I'+MSB,'P'
db 0,_Const
_.PI equ $-ssPI
;
; -->> OUTPUT
;
dw _.OUTP
ssOUTP:
dw l74f3+7 ;text file type???
dw l00c2
db 0
db 'T'+MSB,'UPTUO'
db 0,4
_.OUTP equ $-ssOUTP
;
; -->> INPUT
;
dw _.INPT
ssINPT:
dw l74f3+7 ;text file type???
dw l00c2
db 0
db 'T'+MSB,'UPNI'
db 0,_Ptr
_.INPT equ $-ssINPT
;
; -->> CON
;
dw _.CON
ssCON:
dw l74f3+7 ;text file type???
dw l00b8
db 0
db 'N'+MSB,'OC'
db 0,_Ptr
_.CON equ $-ssCON
;
; -->> TRM
;
dw _.TRM
ssTRM:
dw l74f3+7 ;text file type???
dw l00b8
db 0
db 'M'+MSB,'RT'
db 0,_Ptr
_.TRM equ $-ssTRM
;
; -->> KBD
;
dw _.KBD
ssKBD:
dw l74f3+7 ;text file type???
dw l00ba
db 0
db 'D'+MSB,'BK'
db 0,_Ptr
_.KBD equ $-ssKBD
;
; -->> LST
;
dw _.LST
ssLST:
dw l74f3+7 ;text file type???
dw l00bc
db 0
db 'T'+MSB,'SL'
db 0,_Ptr
_.LST equ $-ssLST
;
; -->> AUX
;
dw _.AUX
ssAUX:
dw l74f3+7 ;text file type???
dw l00be
db 0
db 'X'+MSB,'UA'
db 0,_Ptr
_.AUX equ $-ssAUX
;
; -->> USR
;
dw _.USR
ssUSR:
dw l74f3+7 ;text file type???
dw l00c0
db 0
db 'R'+MSB,'SU'
db 0,_Ptr
_.USR equ $-ssUSR
;
; -->> BUFLEN
;
dw _.BUFL
ssBUFL:
dw l74fb+7 ;byte type
dw l00d1
db 0
db 'N'+MSB,'ELFUB'
db 0,_Ptr
_.BUFL equ $-ssBUFL
;
; -->> HEAPPTR
;
dw _.HEAP
ssHEAP:
dw l74d3+7 ;integer type
dw l00c4
db 0
db 'R'+MSB,'TPPAEH'
db 0,_Ptr
_.HEAP equ $-ssHEAP
;
; -->> RECURPTR
;
dw _.RECUR
ssRECUR:
dw l74d3+7 ;integer type
dw l00c6
db 0
db 'R'+MSB,'TPRUCER'
db 0,_Ptr
_.RECUR equ $-ssRECUR
;
; -->> CONSTPTR
;
dw _.CONSP
ssCONSP:
dw l74d3+7 ;integer type
dw l00a0+1
db 0
db 'R'+MSB,'TPTSNOC'
db 0,_Ptr
_.CONSP equ $-ssCONSP
;
; -->> CONINPTR
;
dw _.CONIP
ssCONIP:
dw l74d3+7 ;integer type
dw l00a3+1
db 0
db 'R'+MSB,'TPNINOC'
db 0,_Ptr
_.CONIP equ $-ssCONIP
;
; -->> CONOUTPTR
;
dw _.CONOP
ssCONOP:
dw l74d3+7 ;integer type
dw l00a6+1
db 0
db 'R'+MSB,'TPTUONOC'
db 0,_Ptr
_.CONOP equ $-ssCONOP
;
; -->> LSTOUTPTR
;
dw _.LSTOP
ssLSTOP:
dw l74d3+7 ;integer type
dw l00a9+1
db 0
db 'R'+MSB,'TPTUOTSL'
db 0,_Ptr
_.LSTOP equ $-ssLSTOP
;
; -->> AUXINPTR
;
dw _.AUXIP
ssAUXIP:
dw l74d3+7 ;integer type
dw l00af+1
db 0
db 'R'+MSB,'TPNIXUA'
db 0,_Ptr
_.AUXIP equ $-ssAUXIP
;
; -->> AUXOUTPTR
;
dw _.AUXOP
ssAUXOP:
dw l74d3+7 ;integer type
dw l00ac+1
db 0
db 'R'+MSB,'TPTUOXUA'
db 0,_Ptr
_.AUXOP equ $-ssAUXOP
;
; -->> USRINPTR
;
dw _.USRIP
ssUSRIP:
dw l74d3+7 ;integer type
dw l00b5+1
db 0
db 'R'+MSB,'TPNIRSU'
db 0,_Ptr
_.USRIP equ $-ssUSRIP
;
; -->> USROUTPTR
;
dw _.USROP
ssUSROP:
dw l74d3+7 ;integer type
dw l00b2+1
db 0
db 'R'+MSB,'TPTUORSU'
db 0,_Ptr
_.USROP equ $-ssUSROP
;
; -->> ERRORPTR
;
dw _.ERRPT
ssERRPT:
dw l74d3+7 ;integer type
dw l00da
db 0
db 'R'+MSB,'TPRORRE'
db 0,_Ptr
_.ERRPT equ $-ssERRPT
;
; -->> CBREAK
;
dw _.CBRK
ssCBRK:
dw l74eb+7
dw l00dd
db 0
db 'K'+MSB,'AERBC'
db 0,_Ptr
_.CBRK equ $-ssCBRK
IntLabTab:
LenLab equ IntLabTab-l731f
;
; Standard type length table
; Note HI-LO entries of definition words
;
dww macro val
db HIGH val
db LOW val
endm
l74d3:
dww 2 ; Length for this type
dww MAXINT ; Max value
dww (-MAXINT-1) ; Min value
dww _Integ ; Type
l74db:
dww 1
dww 255
dww 0
dww _Char
l74e3:
dww 6
dww 0
dww 0
dww _Real
l74eb:
dww 1
dww _TRUE
dww FALSE
dww _Bool
l74f3:
dww (FIBlen+RecLng)
dww 0
dww 0
dww _TxtF
l74fb:
dww 1
dww 255
dww 0
dww _Integ
;
dww (DefSTR+1)
dww 0
dww 0
dww _String
l750b:
dww 0
dww 0
dww 0
dww 0
;
; Table of reserved words
;
l7513:
db 0
dw l7529
db _Byte
dw l7584
db _Addr
dw l75bb
db _Byte
dw l75f5
db _Byte
dw l7604
db _Byte
dw l761d
db _Byte
dw l7634
db -1
;
; Keywords
;
l7529:
dc 'PROGRAM'
l7530:
dc 'END'
l7533:
dc 'FORWARD'
l753a:
dc 'EXTERNAL'
l7542:
dc 'PACKED'
l7548:
dc 'ARRAY'
l754d:
dc 'FILE'
l7551:
dc 'SET'
l7554:
dc 'RECORD'
l755a:
dc 'STRING'
l7560:
dc 'OF'
l7562:
dc 'ABSOLUTE'
l756a:
dc 'THEN'
l756e:
dc 'ELSE'
l7572:
dc 'DO'
l7574:
dc 'UNTIL'
l7579:
dc 'NOT'
l757c:
dc 'NIL'
db 0
l7580:
dc '..'
l7582:
dc ':='
;
; Main block table
; -->> Code is type
;
l7584:
dc 'LABEL'
db 1
dc 'CONST'
db 2
dc 'TYPE'
db 3
l7595:
dc 'VAR'
db 4
dc 'BEGIN'
db 8
l759f:
dc 'OVERLAY'
db 7
l75a7:
dc 'PROCEDURE'
db 5
dc 'FUNCTION'
db 6
db 0
;
; Statement table
;
l75bb:
dc 'BEGIN'
dw l5377
dc 'IF'
dw l53ef
dc 'WHILE'
dw l5424
dc 'REPEAT'
dw l544c
dc 'FOR'
dw l546b
l75da:
dc 'CASE'
dw l5521
dc 'GOTO'
dw l5626
dc 'WITH'
dw l564e
dc 'INLINE'
dw l5698
db 0
l75f5:
dc 'TO'
inc hl
dc 'DOWNTO'
dec hl
db 0
l7600:
db '*'+0x80
db 0
db '/'+0x80
db 1
l7604:
dc 'AND'
db 2
dc 'DIV'
db 3
dc 'MOD'
db 4
dc 'SHL'
db 5
dc 'SHR'
db 6
db 0
l7619:
db '+'+0x80
db 0
db '-'+0x80
db 1
l761d:
dc 'OR'
db 2
dc 'XOR'
db 3
db 0
l7625:
db '='+0x80
db 00000000b
db '<','>'+0x80
db 00001000b
db '>','='+0x80
db 00010000b
db '<','='+0x80
db 00011000b
db '>'+0x80
db 00100000b
db '<'+0x80
db 00101000b
l7634:
dc 'IN'
db 11111111b
db 0
l7638:
dc 'WRITELN'
dw l5ae7
dc 'WRITE'
dw l5ae8
dc 'READLN'
dw l5a32
dc 'READ'
dw l5a33
dc 'DELETE'
dw l5c66
dc 'INSERT'
dw l5c87
dc 'ASSIGN'
dw l5943
dc 'RESET'
dw l59b9
dc 'REWRITE'
dw l59be
dc 'CLOSE'
dw l59db
dc 'ERASE'
dw l5971
dc 'RENAME'
dw l5966
dc 'SEEK'
dw l598c
dc 'GETMEM'
dw l5d94
dc 'NEW'
dw l5d9f
dc 'FREEMEM'
dw l5db4
dc 'DISPOSE'
dw l5dbf
dc 'MARK'
dw l5dd4
dc 'RELEASE'
dw l5dd9
dc 'OVRDRIVE'
dw l5df9
dc 'CRTINIT'
dw l5e38
dc 'CRTEXIT'
dw l5e3d
dc 'GOTOXY'
dw l5d6d
dc 'CLRSCR'
dw l5e42
dc 'CLREOL'
dw l5e48
dc 'NORMVIDEO'
dw l5e4d
dc 'HIGHVIDEO'
dw l5e4d
dc 'LOWVIDEO'
dw l5e52
dc 'INSLINE'
dw l5e57
dc 'DELLINE'
dw l5e5c
dc 'DELAY'
dw l5d89
dc 'BLOCKREAD'
dw l5c16
dc 'BLOCKWRITE'
dw l5c1e
dc 'RANDOMIZE'
dw l5d83
dc 'MOVE'
dw l5e05
dc 'FILLCHAR'
dw l5e1a
dc 'EXIT'
dw l5e61
dc 'HALT'
dw l5e67
dc 'PORT'
dw l5e6d
dc 'STACKPTR'
dw l5e78
dc 'FLUSH'
dw l59ab
dc 'EXECUTE'
dw l597e
dc 'CHAIN'
dw l5979
dc 'STR'
dw l5cba
dc 'VAL'
dw l5d22
dc 'BDOS'
dw l6553
dc 'BIOS'
dw l651e
db 0
l77b1:
dc 'CHR'
dw l6425
dc 'ORD'
dw l6411
dc 'COPY'
dw l6460
dc 'LENGTH'
dw l6441
dc 'POS'
dw l6452
dc 'CONCAT'
dw l6481
dc 'SUCC'
dw l63d4
dc 'PRED'
dw l63d7
dc 'UPCASE'
dw l6437
dc 'TRUNC'
dw l63be
dc 'ROUND'
dw l63c3
dc 'ODD'
dw l6401
dc 'ABS'
dw l6371
dc 'SQR'
dw l6360
dc 'SQRT'
dw l6385
dc 'SIN'
dw l638a
dc 'COS'
dw l638f
dc 'ARCTAN'
dw l6394
dc 'LN'
dw l6399
dc 'EXP'
dw l639e
dc 'INT'
dw l63a3
dc 'FRAC'
dw l63a8
dc 'RANDOM'
dw l64ac
dc 'PARAMCOUNT'
dw l649c
dc 'PARAMSTR'
dw l64a1
dc 'LO'
dw l63e1
dc 'HI'
dw l63eb
dc 'SWAP'
dw l63f6
dc 'PTR'
dw l642b
dc 'IORESULT'
dw l64c4
dc 'EOF'
dw l64c9
dc 'EOLN'
dw l64df
dc 'SEEKEOF'
dw l64d5
dc 'SEEKEOLN'
dw l64da
dc 'FILESIZE'
dw l64fa
dc 'FILEPOS'
dw l64f2
dc 'KEYPRESSED'
dw l640c
dc 'MEMAVAIL'
dw l6514
dc 'MAXAVAIL'
dw l6519
dc 'PORT'
dw l65bf
dc 'STACKPTR'
dw l65ca
dc 'ADDR'
dw l6576
dc 'SIZEOF'
dw l659d
dc 'BDOSHL'
dw l6553
dc 'BDOS'
dw l6554
dc 'BIOSHL'
dw l651e
dc 'BIOS'
dw l651f
db 0
l78fa:
dc 'MEM'
dw 0
db 0
;
; Start of dynamic data
; - originally at page boundary - here : 7900h
;
; Dynamic data area starts - shared by editor and compiler most
;
CmpTyp:
db 1ah ; Compile flag:
; 0: Compile to memory
; 1: Compile to .COM/.CHN file
; 2: Searching
l7901:
db 'd' ; Error code
CodePC:
db 'SE' ; Code pointer
l7904:
db 'EK' ; Code start address
l7906:
db 'EO' ; Code end address
DataBeg:
db 'L',0ceh ; Start of data
l790a:
db 0dah,'d' ; End of code address
l790c:
db 'FI' ; Current editor address
IncFlg:
db 'L' ; Memory read flag (0 is read)
l790f:
db 'ESIZ',0c5h,0fah,'dFILEPO',0d3h,0f2h
db 'dKEYPRESSE',0c4h,0ch,'dMEMAVAI',0cch
;
; FCB of source file
;
FFCB: ;36 bytes???
db 14h
db 'eMAXAVAI'
db 0cch
db 19h,'ePOR',0d4h,0bfh,'eSTACKPT'
db 0d2h,0cah,'eADD',0d2h,'v'
db 'eSI'
;
; DISK BUFFER
;
TmpBuff:
db 'ZEO',0c6h,9dh,'eBDOS'
db 'H',0cch,'SeBDO',0d3h,'TeBIOSH'
db 0cch,1eh,'eBIO',0d3h,1fh,'e'
db 0,'ME',0cdh,0,0,0
l7980:: ;;**
l79d7 equ TmpBuff+RecLng ; Start of source line
l7a57 equ l79d7+RecLng
l7ad7 equ l7a57+RecLng ; Top of used memory on start
Envir1 equ l7ad7+RecLng
l7b58 equ Envir1+1 ; Value of symbol
l7b59 equ l7b58+1
l7b5a equ l7b59+1 ; Type table
l7b5c equ l7b5a+2 ; Type
l7b5d equ l7b5c+1
l7b5e equ l7b5d+1 ; Lo set limit
l7b60 equ l7b5e+2 ; Hi set limit
l7b62 equ l7b60+2 ; Length of type
Envir2 equ l7b62+2
l7b65 equ Envir2+1
l7b69 equ l7b65+4
l7b6b equ l7b69+2
l7b6d equ l7b6b+2 ; Last memory address
l7b6f equ l7b6d+2 ; TEMP
l7b71 equ l7b6f+2 ; TEMP
l7b72 equ l7b71+1 ; EDT: Pointer to delimters
LabPtr equ l7b72+1 ; Label pointer
l7b74 equ LabPtr+1 ; EDT: Edited line
PrevLabPtr equ l7b74+1 ; Previous label pointer
l7b77 equ PrevLabPtr+2 ; Top of available memory
l7b79 equ l7b77+2
CurLab equ l7b79+2 ; Current label pointer
l7b7d equ CurLab+2
l7b7f equ l7b7d+2
l7b81 equ l7b7f+2
l7b83 equ l7b81+2
l7b85 equ l7b83+2
l7b87 equ l7b85+2
l7b88 equ l7b87+1
l7b89 equ l7b88+1
l7b8b equ l7b89+2
l7b8d equ l7b8b+2
l7b8f equ l7b8d+2
l7b90 equ l7b8f+1
l7b91 equ l7b90+1 ; ???
l7b92 equ l7b91+1 ; ???
curtype_l7b93 equ l7b92+1 ; Type
l7b94 equ curtype_l7b93+1 ; ???
l7b95 equ l7b94+1
l7b96 equ l7b95+1 ; OVERLAY number
l7b97 equ l7b96+1 ; PROCEDURE (=0) or FUNCTION (<>0)
l7b98 equ l7b97+1
l7b99 equ l7b98+1 ; Overlay flag (-1)
l7b9a equ l7b99+1
l7b9b equ l7b9a+1
l7b9c equ l7b9b+1
l7b9d equ l7b9c+1 ; Option bits
l7b9e equ l7b9d+1 ; Local PROCEDURE/FUNCTION options
l7b9f equ l7b9e+1
l7ba0 equ l7b9f+1 ; End on break
l7ba1 equ l7ba0+1
l7ba2 equ l7ba1+1 ; End of file
l7ba3 equ l7ba2+1
l7ba4 equ l7ba3+1
l7ba6 equ l7ba4+2
l7ba7 equ l7ba6+1
l7ba9 equ l7ba7+2
l7bab equ l7ba9+2 ; Data pointer for overlay
l7bb0 equ l7bab+5 ; Length of overlay
l7bb2 equ l7bb0+2 ; OVERLAY file name
l7bbd equ l7bb2+11
l7bbe equ l7bbd+1
FirstVAR equ l7bbe+2
l7bc1 equ FirstVAR+1
l7bc2 equ l7bc1+1
l7bc4 equ l7bc2+2
l7bc6 equ l7bc4+2
l7bc7 equ l7bc6+1 ; Depth for WITH
l7bc8 equ l7bc7+1
l7bc9 equ l7bc8+1
l7bca equ l7bc9+1
l7bcc equ l7bca+2
Env_PC equ l7bcc+9
l7bd7 equ Env_PC+2 ; Source pointer
l7bd9 equ l7bd7+2 ; Dtto.
RRN_stat equ l7bd9+2 ; File access
RecPtr equ RRN_stat +1 ; Record pointer
RRN_off equ RecPtr+1 ; Record base
MemsTop equ RRN_off+2
COMsTop equ MemsTop+2 ; Top of .COM file
BackLevel equ COMsTop+2 ; Back fix level
l7be4 equ BackLevel+1 ; Saved top of .COM file
INCsTop equ l7be4+2
l7be8 equ INCsTop+2
l7be9 equ l7be8+1
l7beb equ l7be9+2
l7bed equ l7beb+2
l7bef equ l7bed+2 ; Line count
l7bf5 equ l7bef+6 ; Start of text
end
savebin "tp.com",begin,end-begin
LABELSLIST "../../us/user.l"