load.asm 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include once <alloc.asm>
  2. #include once <free.asm>
  3. #include once <print.asm>
  4. LOAD_CODE:
  5. ; This function will implement the LOAD CODE Routine
  6. ; Parameters in the stack are HL => String with LOAD name
  7. ; (only first 12 chars will be taken into account)
  8. ; DE = START address of CODE to save
  9. ; BC = Length of data in bytes
  10. ; A = 1 => LOAD 0 => Verify
  11. ;- PROC
  12. ;- LOCAL LOAD_CONT, LOAD_CONT2, LOAD_CONT3
  13. ;- LOCAL LD_BYTES
  14. ;- LOCAL LOAD_HEADER
  15. ;- LOCAL LD_LOOK_H
  16. ;- LOCAL HEAD1
  17. ;- LOCAL TMP_HEADER
  18. ;- LOCAL LD_NAME
  19. ;- LOCAL LD_CH_PR
  20. ;- LOCAL LOAD_END
  21. ;- LOCAL VR_CONTROL, VR_CONT_1, VR_CONT_2
  22. HEAD1 EQU MEM0 + 8
  23. ; Uses CALC Mem for temporary storage
  24. ; Must skip first 8 bytes used by
  25. ; PRINT routine
  26. TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage
  27. LD_BYTES EQU 0556h ; ROM Routine LD-BYTES
  28. TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG
  29. ;- pop hl ; Return address
  30. ;- pop af ; A = 1 => LOAD; A = 0 => VERIFY
  31. ;- pop bc ; data length in bytes
  32. ;- pop de ; address start
  33. ;- ex (sp), hl ; CALLE => now hl = String
  34. __LOAD_CODE: ; INLINE version
  35. ;- push ix ; saves IX
  36. ;- ld (TMP_FLAG), a ; Stores verify/load flag
  37. ; Prepares temporary 1st header descriptor
  38. ;- ld ix, HEAD1
  39. ;- ld (ix + 0), 3 ; ZXBASIC ALWAYS uses CODE
  40. ;- ld (ix + 1), 0FFh ; Wildcard for empty string
  41. ;- ld (ix + 11), c
  42. ;- ld (ix + 12), b ; Store length in bytes
  43. ;- ld (ix + 13), e
  44. ;- ld (ix + 14), d ; Store address in bytes
  45. ;- ld a, h
  46. ;- or l
  47. ;- ld b, h
  48. ;- ld c, l
  49. ;- jr z, LOAD_HEADER ; NULL STRING => LOAD ""
  50. ;- ld c, (hl)
  51. ;- inc hl
  52. ;- ld b, (hl)
  53. ;- inc hl
  54. ;- ld a, b
  55. ;- or c
  56. ;- jr z, LOAD_CONT2 ; NULL STRING => LOAD ""
  57. ; Fill with blanks
  58. ;- push hl
  59. ;- push bc
  60. ;- ld hl, HEAD1 + 2
  61. ;- ld de, HEAD1 + 3
  62. ;- ld bc, 8
  63. ;- ld (hl), ' '
  64. ;- ldir
  65. ;- pop bc
  66. ;- pop hl
  67. LOAD_HEADER:
  68. ;- ex de, hl ; Saves HL in DE
  69. ;- ld hl, 10
  70. ;- or a
  71. ;- sbc hl, bc ; Test BC > 10?
  72. ;- ex de, hl ; Retrieve HL
  73. ;- jr nc, LOAD_CONT ; Ok BC <= 10
  74. ;- ld bc, 10 ; BC at most 10 chars
  75. LOAD_CONT:
  76. ;- ld de, HEAD1 + 1
  77. ;- ldir ; Copy String block NAME in header
  78. LOAD_CONT2:
  79. ;- ld bc, 17; 2nd Header
  80. ;- call __MEM_ALLOC
  81. ;- ld a, h
  82. ;- or l
  83. ;- jr nz, LOAD_CONT3; there's memory
  84. ;- ld a, ERROR_OutOfMemory
  85. ;- jp __ERROR
  86. LOAD_CONT3:
  87. ;- ld (TMP_HEADER), hl
  88. ;- push hl
  89. ;- pop ix
  90. ;; LD-LOOK-H --- RIPPED FROM ROM at 0x767
  91. LD_LOOK_H:
  92. ;- push ix ; save IX
  93. ;- ld de, 17 ; seventeen bytes
  94. ;- xor a ; reset zero flag
  95. ;- scf ; set carry flag
  96. ;- call LD_BYTES ; routine LD-BYTES loads a header from tape
  97. ;- ; to second descriptor.
  98. ;- pop ix ; restore IX
  99. ;- jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found.
  100. ;- ld c, 80h ; C has bit 7 set to indicate header type mismatch as
  101. ;- ; a default startpoint.
  102. ;- ld a, (ix + 0) ; compare loaded type
  103. ;- cp 3 ; with expected bytes header
  104. ;- jr nz, LD_TYPE ; forward to LD-TYPE with mis-match.
  105. ;- ld c, -10 ; set C to minus ten - will count characters
  106. ;- ; up to zero.
  107. LD_TYPE:
  108. ;- cp 4 ; check if type in acceptable range 0 - 3.
  109. ;- jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over.
  110. ;- ; else A indicates type 0-3.
  111. ;- call PRINT_TAPE_MESSAGES; Print tape msg
  112. ;- ld hl, HEAD1 + 1 ; point HL to 1st descriptor.
  113. ;- ld de, (TMP_HEADER) ; point DE to 2nd descriptor.
  114. ;- ld b, 10 ; the count will be ten characters for the
  115. ;- ; filename.
  116. ;- ld a, (hl) ; fetch first character and test for
  117. ;- inc a ; value 255.
  118. ;- jr nz, LD_NAME ; forward to LD-NAME if not the wildcard.
  119. ; but if it is the wildcard, then add ten to C which is minus ten for a type
  120. ; match or -128 for a type mismatch. Although characters have to be counted
  121. ; bit 7 of C will not alter from state set here.
  122. ;- ld a, c ; transfer $F6 or $80 to A
  123. ;- add a, b ; add 10
  124. ;- ld c, a ; place result, zero or -118, in C.
  125. ; At this point we have either a type mismatch, a wildcard match or ten
  126. ; characters to be counted. The characters must be shown on the screen.
  127. ;; LD-NAME
  128. LD_NAME:
  129. ;- inc de ; address next input character
  130. ;- ld a, (de) ; fetch character
  131. ;- cp (hl) ; compare to expected
  132. ;- inc hl ; address next expected character
  133. ;- jr nz, LD_CH_PR ; forward to LD-CH-PR with mismatch
  134. ;- inc c ; increment matched character count
  135. ;; LD-CH-PR
  136. LD_CH_PR:
  137. ;- call __PRINTCHAR ; PRINT-A prints character
  138. ;- djnz LD_NAME ; loop back to LD-NAME for ten characters.
  139. ;- bit 7, c ; test if all matched
  140. ;- jr nz, LD_LOOK_H ; back to LD-LOOK-H if not
  141. ; else print a terminal carriage return.
  142. ;- ld a, 0Dh ; prepare carriage return.
  143. ;- call __PRINTCHAR ; PRINT-A outputs it.
  144. ;- ld a, (HEAD1)
  145. ;- cp 03 ; Only "bytes:" header is used un ZX BASIC
  146. ;- jr nz, LD_LOOK_H
  147. ; Ok, ready to check for bytes start and end
  148. VR_CONTROL:
  149. ;- ld e, (ix + 11) ; fetch length of new data
  150. ;- ld d, (ix + 12) ; to DE.
  151. ;- ld hl, HEAD1 + 11
  152. ;- ld a, (hl) ; fetch length of old data (orig. header)
  153. ;- inc hl
  154. ;- ld h, (hl) ; to HL
  155. ;- ld l, a
  156. ;- or h ; check length of old for zero. (Carry reset)
  157. ;- jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified e.g. LOAD "x" CODE
  158. ;- sbc hl, de
  159. ;- jr nz, LOAD_ERROR ; Lenghts don't match
  160. VR_CONT_1:
  161. ;- ld hl, HEAD1 + 13 ; fetch start of old data (orig. header)
  162. ;- ld a, (hl)
  163. ;- inc hl
  164. ;- ld h, (hl)
  165. ;- ld l, a
  166. ;- or h ; check start for zero (unespecified)
  167. ;- jr nz, VR_CONT_2 ; Jump if there was a start
  168. ;- ld l, (ix + 13) ; otherwise use destination in header
  169. ;- ld h, (ix + 14) ; and load code at addr. saved from
  170. VR_CONT_2:
  171. lda z80_l ;- push hl
  172. pha
  173. lda z80_h
  174. pha
  175. ;- pop ix ; Transfer load addr to IX
  176. ;- ld a, (TMP_FLAG) ; load verify/load flag
  177. ;- sra a ; shift bit 0 to Carry (1 => Load, 0 = Verify), A = 0
  178. ;- dec a ; a = 0xFF (Data)
  179. ;- call LD_BYTES
  180. ;- jr c, LOAD_END ; if carry, load/verification was ok
  181. LOAD_ERROR:
  182. ; Sets ERR_NR with Tape Loading, and returns
  183. ;- ld a, ERROR_TapeLoadingErr
  184. ;- ld (ERR_NR), a
  185. LOAD_END:
  186. pla ;- pop ix ; Recovers stack frame pointer
  187. sta z80_ix+1
  188. pla
  189. sta z80_ix
  190. ;- ld hl, (TMP_HEADER) ; Recovers tmp_header pointer
  191. ;- jp MEM_FREE ; Returns via FREE_MEM, freeing tmp header
  192. ;- ENDP
  193. PRINT_TAPE_MESSAGES:
  194. ;- PROC
  195. ;- LOCAL LOOK_NEXT_TAPE_MSG
  196. ;- LOCAL PRINT_TAPE_MSG
  197. ; Print tape messages according to A value
  198. ; Each message starts with a carriage return and
  199. ; ends with last char having its bit 7 set
  200. ; A = 0 => '\nProgram: '
  201. ; A = 1 => '\nNumber array: '
  202. ; A = 2 => '\nCharacter array: '
  203. ; A = 3 => '\nBytes: '
  204. lda z80_c ;- push bc
  205. pha
  206. lda z80_b
  207. pha
  208. ;- ld hl,09C0h ; address base of last 4 tape messages
  209. lda z80_a ;- ld b,a
  210. sta z80_b
  211. inc z80_b ;- inc b ; avoid 256-loop if b == 0
  212. ;- ld a,0Dh ; Msg start mark
  213. ; skip memory bytes looking for next tape msg entry
  214. ; each msg ends when 0Dh is fond
  215. LOOK_NEXT_TAPE_MSG:
  216. inc z80_l ;- inc hl ; Point to next char
  217. bne *+4
  218. inc z80_h
  219. ;- cp (hl) ; Is it 0Dh?
  220. ;- jr nz, LOOK_NEXT_TAPE_MSG
  221. ; Ok next message found
  222. ;- djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip
  223. PRINT_TAPE_MSG:
  224. ; Ok. This will print bytes after (HL)
  225. ; until one of them has bit 7 set
  226. ldy #$00 ;- ld a,(hl)
  227. lda (z80_hl),y
  228. sta z80_a
  229. and #$7F ;- and $7F ; Clear bit 7 of A
  230. jsr __PRINTCHAR ;- call __PRINTCHAR
  231. ldy #$00 ;- ld a,(hl)
  232. lda (z80_hl),y
  233. sta z80_a
  234. inc z80_l ;- inc hl
  235. bne *+4
  236. inc z80_h
  237. clc ;- add a,a ; Carry if A >= 128
  238. adc z80_a
  239. jcs PRINT_TAPE_MSG ;- jr nc, PRINT_TAPE_MSG
  240. pla ;- pop bc
  241. sta z80_b
  242. pla
  243. sta z80_c
  244. rts ;- ret
  245. ;- ENDP