]> git.sur5r.net Git - cc65/blob - libsrc/atari/ser/atrrdev.s
add serial driver for Atari, still contains much debug code
[cc65] / libsrc / atari / ser / atrrdev.s
1 ;
2 ; Christian Groessler, Dec-2001
3 ; converted to driver interface Nov-2013
4 ;
5 ; RS232 routines using the R: device (currently tested with an 850 only)
6 ;
7
8         .include        "zeropage.inc"
9         .include        "ser-kernel.inc"
10         .include        "ser-error.inc"
11         .include        "atari.inc"
12
13 .macro  pushall
14         php
15         pha
16         txa
17         pha
18         tya
19         pha
20 .endmacro
21 .macro  pullall
22         pla
23         tay
24         pla
25         tax
26         pla
27         plp
28 .endmacro
29
30 .ifdef __ATARIXL__
31 .macro print_string text
32 .endmacro
33 .else
34 .macro print_string text
35         .local  @start, @cont
36         jmp     @cont
37 @start:  .byte   text, ATEOL
38 @cont:   php
39         pha
40         txa
41         pha
42         tya
43         pha
44         ldx     #0              ; channel 0
45         lda     #<@start
46         sta     ICBAL,x         ; address
47         lda     #>@start
48         sta     ICBAH,x
49         lda     #<(@cont - @start)
50         sta     ICBLL,x         ; length
51         lda     #>(@cont - @start)
52         sta     ICBLH,x
53         lda     #PUTCHR
54         sta     ICCOM,x
55         jsr     CIOV
56         pla
57         tay
58         pla
59         tax
60         pla
61         plp
62 .endmacro
63 .endif
64
65 ; ------------------------------------------------------------------------
66 ; Header. Includes jump table
67
68 .segment        "JUMPTABLE"
69
70 ; Driver signature
71
72         .byte   $73, $65, $72           ; "ser"
73         .byte   SER_API_VERSION         ; Serial API version number
74
75 ; Library reference
76
77 libref: .addr   $0000
78
79 ; Jump table
80
81         .word   SER_INSTALL
82         .word   SER_UNINSTALL
83         .word   SER_OPEN
84         .word   SER_CLOSE
85         .word   SER_GET
86         .word   SER_PUT
87         .word   SER_STATUS
88         .word   SER_IOCTL
89         .word   SER_IRQ
90
91
92         .rodata
93
94 rdev:   .byte   "R:", ATEOL, 0
95 bauds:  .byte   1               ; SER_BAUD_45_5
96         .byte   2               ; SER_BAUD_50
97         .byte   4               ; SER_BAUD_75
98         .byte   5               ; SER_BAUD_110
99         .byte   6               ; SER_BAUD_134_5
100         .byte   7               ; SER_BAUD_150
101         .byte   8               ; SER_BAUD_300
102         .byte   9               ; SER_BAUD_600
103         .byte   10              ; SER_BAUD_1200
104         .byte   11              ; SER_BAUD_1800
105         .byte   12              ; SER_BAUD_2400
106         .byte   0               ; SER_BAUD_3600
107         .byte   13              ; SER_BAUD_4800
108         .byte   0               ; SER_BAUD_7200
109         .byte   14              ; SER_BAUD_9600
110         .byte   0               ; SER_BAUD_19200
111         .byte   0               ; SER_BAUD_38400
112         .byte   0               ; SER_BAUD_57600
113         .byte   0               ; SER_BAUD_115200
114         .byte   0               ; SER_BAUD_230400
115         .byte   0               ; SER_BAUD_31250
116         .byte   0               ; SER_BAUD_62500
117         .byte   3               ; SER_BAUD_56_875
118 num_bauds       =       * - bauds
119 databits:
120         .byte   48              ; SER_BITS_5
121         .byte   32              ; SER_BITS_6
122         .byte   16              ; SER_BITS_7
123         .byte   0               ; SER_BITS_8
124 num_databits    =       * - databits
125 parities:
126         .byte   0               ; SER_PAR_NONE
127         .byte   4+1             ; SER_PAR_ODD
128         .byte   2+8             ; SER_PAR_EVEN
129         ;.byte  0               ; SER_PAR_MARK
130         ;.byte  0               ; SER_PAR_SPACE
131 num_parities    =       * - parities
132
133         .bss
134
135 ; receive buffer
136 RECVBUF_SZ = 256
137 recv_buf: .res  RECVBUF_SZ
138
139 cm_run: .res    1       ; concurrent mode running?
140
141         .data
142
143 rshand: .word   $ffff
144
145 ; jump table into main program, initialized from libref
146 my_newfd:
147         .byte   $4C
148         .word   0
149 my__close:
150         .byte   $4C
151         .word   0
152 my_pushax:
153         .byte   $4C
154         .word   0
155 my_popax:
156         .byte   $4C
157         .word   0
158 my_findfreeiocb:
159         .byte   $4C
160         .word   0
161 my___do_oserror:
162         .byte   $4C
163         .word   0
164 my_fddecusage:
165         .byte   $4C
166         .word   0
167 my_fdtoiocb:
168         .byte   $4C
169         .word   0
170 my___inviocb:
171         .byte   $4C
172         .word   0
173 my_clriocb:
174         .byte   $4C
175         .word   0
176 my_CIOV:
177         .byte   $4C
178         .word   0
179
180         .code
181
182 invbaud:
183         lda     #<SER_ERR_BAUD_UNAVAIL
184         ldx     #>SER_ERR_BAUD_UNAVAIL
185 openerr:
186         rts
187
188
189 ;----------------------------------------------------------------------------
190 ; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
191 ; Must return an SER_ERR_xx code in a/x.
192
193 SER_OPEN:
194         jsr     do_open
195         bne     openerr
196
197 ; set line parameters
198         lda     rshand
199         ldx     #0
200         jsr     my_fdtoiocb     ; get iocb index into X
201         bmi     openerr         ; shouldn't happen
202         tax
203
204         ; set baud rate, word size, stop bits and ready monitoring
205
206         ; build ICAX1 value
207
208         jsr     dump
209         jsr     print_open_txt
210         jsr     print_iocb_txt
211         jsr     dump_iocb_num
212         jsr     nl
213
214         ldy     #SER_PARAMS::BAUDRATE
215         lda     (ptr1),y
216         cmp     #num_bauds
217         bcs     invbaud
218
219         tay
220         lda     bauds,y
221         beq     invbaud
222         sta     ICAX1,x
223
224         ldy     #SER_PARAMS::DATABITS
225         lda     (ptr1),y
226         cmp     #num_databits
227         bcs     init_err
228
229         tay
230         lda     databits,y
231         ora     ICAX1,x
232         sta     ICAX1,x
233
234         ldy     #SER_PARAMS::STOPBITS
235         lda     (ptr1),y
236         clc
237         ror     a
238         ror     a
239         ora     ICAX1,x
240         sta     ICAX1,x
241
242         jsr     dump_aux1
243
244         lda     #36             ; xio 36, baud rate
245         sta     ICCOM,x
246         lda     #0
247         ;ICAX2 = 0, monitor nothing
248         sta     ICAX2,x
249         sta     ICBLL,x
250         sta     ICBLH,x
251         sta     ICBAL,x
252         sta     ICBAH,x
253         jsr     my_CIOV
254         bmi     cioerr
255
256         ; check if the handshake setting is valid
257         ldy     #SER_PARAMS::HANDSHAKE
258         lda     (ptr1),y
259         cmp     #SER_HS_HW      ; this is all we support
260         bne     init_err
261
262         ; set handshake lines
263         lda     #34             ; xio 34, set cts, dtr etc
264         sta     ICCOM,x
265         lda     #192+48+3       ; DTR on, RTS on, XMT on
266         sta     ICAX1,x
267         jsr     my_CIOV
268         bmi     cioerr
269
270         ; set translation and parity
271         ldy     #SER_PARAMS::PARITY
272         lda     (ptr1),y
273         cmp     #num_parities
274         bcs     init_err
275
276         tay
277         lda     parities,y
278         ora     #32             ; no translation
279         sta     ICAX1,x
280
281         jsr     dump_aux1
282
283         lda     #38             ; xio 38, translation and parity
284         sta     ICCOM,x
285         jsr     my_CIOV
286         bmi     cioerr
287
288         lda     #<SER_ERR_OK
289         tax                             ; A is zero
290         rts
291
292 inverr: jmp     my___inviocb
293
294 cioerr:
295         ; @@@ need to close IOCB here
296         jsr     my_fddecusage   ; decrement usage counter of fd as open failed
297
298 init_err:
299         ldx     #0
300         lda     #SER_ERR_INIT_FAILED
301         rts
302
303 ;---- open the device
304
305 do_open:
306         jsr     my_findfreeiocb
307         bne     init_err
308         txa
309         tay                     ; move iocb # into Y
310         lda     #3
311         sta     tmp3            ; name length + 1
312         lda     #<rdev
313         ldx     #>rdev
314         jsr     my_newfd
315         tya
316         bcs     @doopen         ; C set: open needed / device not already open
317
318         pha
319         jsr     SER_CLOSE       ;** shut down if started  @@@TODO check this out!!
320         pla
321
322 @doopen:tax
323         pha
324         jsr     my_clriocb
325         pla
326         tax
327         lda     #<rdev
328         sta     ICBAL,x
329         lda     #>rdev
330         sta     ICBAH,x
331         lda     #OPEN
332         sta     ICCOM,x
333
334         lda     #$0D            ; mode in+out+concurrent
335         sta     ICAX1,x
336         lda     #0
337         sta     ICAX2,x
338         sta     ICBLL,x         ; zap buf len
339         sta     ICBLH,x
340         jsr     my_CIOV
341         bmi     cioerr
342
343         lda     tmp2            ; get fd (from newfd)
344         sta     rshand
345         ldx     #0
346         stx     rshand+1
347         txa
348         rts
349
350 ;----------------------------------------------------------------------------
351 ; CLOSE: Close the port, disable interrupts and flush the buffer. Called
352 ; without parameters. Must return an error code in a/x.
353 ;
354
355 SER_CLOSE:
356         pushall
357         print_string "SER_CLOSE called"
358         pullall
359         lda     rshand
360         cmp     #$ff
361         beq     @done
362
363         pushall
364         print_string "SER_CLOSE do work"
365         pullall
366
367         ldx     rshand+1
368         ;jsr     my_pushax
369         jsr     my__close
370         ldx     #$ff
371         stx     rshand
372         stx     rshand+1
373         inx
374         stx     cm_run
375 @done:  lda     #<SER_ERR_OK
376         ldx     #>SER_ERR_OK
377         pushall
378         print_string "SER_CLOSE returns"
379         pullall
380         rts
381
382 ;----------------------------------------------------------------------------
383 ; SER_GET: Will fetch a character from the receive buffer and store it into the
384 ; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
385 ; return.
386 ;
387
388 SER_GET:
389         ldy     rshand
390         cpy     #$ff
391         bne     @work           ; work only if initialized
392         lda     #SER_ERR_NOT_OPEN
393         bne     nierr
394
395 @work:  lda     rshand
396         ldx     #0
397         jsr     my_fdtoiocb
398         tax
399         lda     cm_run          ; concurrent mode already running?
400         bne     @go
401         jsr     ena_cm          ; turn on concurrent mode
402
403 @go:    ; check whether there is any input available
404
405         lda     #STATIS         ; status request, returns bytes pending
406         sta     ICCOM,x
407         jsr     my_CIOV
408         bmi     ser_error
409
410         lda     DVSTAT+1        ; get byte count pending
411         ora     DVSTAT+2
412         beq     @nix_da         ; no input waiting...
413
414         ; input is available: get it!
415
416         lda     #GETCHR         ; get raw bytes
417         sta     ICCOM,x         ; in command code
418         lda     #0
419         sta     ICBLL,x
420         sta     ICBLH,x
421         sta     ICBAL,x
422         sta     ICBAH,x
423         jsr     my_CIOV         ; go get it
424         bmi     ser_error
425
426         ldx     #0
427         sta     (ptr1,x)        ; return received byte
428         txa
429         rts
430
431 @nix_da:lda     #SER_ERR_NO_DATA
432         ldx     #0
433         rts
434
435 ser_error:
436         lda     #SER_ERR_OVERFLOW       ; there is no large selection of serial error codes... :-/
437         ldx     #0
438         rts
439
440 nierr:  ldx     #0
441         rts
442
443 ;----------------------------------------------------------------------------
444 ; SER_PUT: Output character in A.
445 ; Must return an error code in a/x.
446 ;
447
448 SER_PUT:
449         ldy     rshand
450         cpy     #$ff
451         bne     @work           ; work only if initialized
452         lda     #SER_ERR_NOT_OPEN
453         bne     nierr
454
455 @work:  pha                     ; char to write
456         lda     rshand
457         ldx     #0
458         jsr     my_fdtoiocb
459         tax
460
461         jsr     print_put_txt
462         pla
463         pha
464         jsr     dump_hex        ; dump char to write
465         jsr     print_iocb_txt
466         jsr     dump_iocb_num
467         jsr     nl
468
469         lda     cm_run          ; concurrent mode already running?
470         bne     @go
471         jsr     ena_cm          ; turn on concurrent mode
472
473         ; @@@TODO:       check output buffer overflow
474 @go:    lda     #PUTCHR         ; put raw bytes
475         sta     ICCOM,x         ; in command code
476         lda     #0
477         sta     ICBLL,x
478         sta     ICBLH,x
479         sta     ICBAL,x
480         sta     ICBAH,x
481         pla                     ; get the char back
482         jsr     my_CIOV         ; go do it
483         bmi     ser_error
484         lda     #0
485         tax
486         rts
487
488 ;----------------------------------------------------------------------------
489 ; SER_STATUS: Return the status in the variable pointed to by ptr1.
490 ; Must return an error code in a/x.
491 ;
492
493 SER_STATUS:
494         ; fall through to SER_IOCTL
495
496 ;----------------------------------------------------------------------------
497 ; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
498 ; specific data in ptr1, and the ioctl code in A.
499 ; Must return an error code in a/x.
500 ;
501
502 SER_IOCTL:
503         lda     #<SER_ERR_INV_IOCTL     ; We don't support ioclts for now
504         ldx     #>SER_ERR_INV_IOCTL
505         rts
506
507 ;----------------------------------------------------------------------------
508 ; SER_IRQ: Not used on the Atari
509 ;
510
511 SER_IRQ     = $0000
512
513 ;----------------------------------------------------------------------------
514 ; SER_INSTALL routine. Is called after the driver is loaded into memory. If
515 ; possible, check if the hardware is present.
516 ; Must return an SER_ERR_xx code in a/x.
517
518 SER_INSTALL:
519
520         ;print_string "SER_INSTALL with error"
521         ;brk
522         ;lda     #42
523         ;ldx     #0
524         ;rts
525
526         ; check if R: device is installed
527
528         ldy     #0
529 search: lda     HATABS,y                ; get device name
530         cmp     #'R'
531         beq     found
532         iny
533         iny
534         iny
535         cpy     #MAXDEV
536         bcc     search
537
538 ; R: device not found, return error
539
540         lda     #<SER_ERR_NO_DEVICE
541         ldx     #0
542         rts
543
544 ; R: device found, initialize jump table into main program
545
546 found:  lda     ptr3
547         pha
548         lda     ptr3+1
549         pha
550         lda     libref
551         sta     ptr3
552         lda     libref+1
553         sta     ptr3+1
554
555         ldy     #0
556         lda     (ptr3),y
557         sta     my_newfd+1
558         iny
559         lda     (ptr3),y
560         sta     my_newfd+2
561         iny
562
563         lda     (ptr3),y
564         sta     my__close+1
565         iny
566         lda     (ptr3),y
567         sta     my__close+2
568         iny
569
570         lda     (ptr3),y
571         sta     my_pushax+1
572         iny
573         lda     (ptr3),y
574         sta     my_pushax+2
575         iny
576
577         lda     (ptr3),y
578         sta     my_popax+1
579         iny
580         lda     (ptr3),y
581         sta     my_popax+2
582         iny
583
584         lda     (ptr3),y
585         sta     my_findfreeiocb+1
586         iny
587         lda     (ptr3),y
588         sta     my_findfreeiocb+2
589         iny
590
591         lda     (ptr3),y
592         sta     my___do_oserror+1
593         iny
594         lda     (ptr3),y
595         sta     my___do_oserror+2
596         iny
597
598         lda     (ptr3),y
599         sta     my_fddecusage+1
600         iny
601         lda     (ptr3),y
602         sta     my_fddecusage+2
603         iny
604
605         lda     (ptr3),y
606         sta     my_fdtoiocb+1
607         iny
608         lda     (ptr3),y
609         sta     my_fdtoiocb+2
610         iny
611
612         lda     (ptr3),y
613         sta     my___inviocb+1
614         iny
615         lda     (ptr3),y
616         sta     my___inviocb+2
617         iny
618
619         lda     (ptr3),y
620         sta     my_clriocb+1
621         iny
622         lda     (ptr3),y
623         sta     my_clriocb+2
624         iny
625
626         lda     (ptr3),y
627         sta     my_CIOV+1
628         iny
629         lda     (ptr3),y
630         sta     my_CIOV+2
631         ;iny
632
633         pla
634         sta     ptr3+1
635         pla
636         sta     ptr3
637
638         lda     #<SER_ERR_OK
639         tax                     ; A is zero
640         rts
641
642 ;----------------------------------------------------------------------------
643 ; SER_UNINSTALL routine. Is called before the driver is removed from memory.
644 ; Must return an SER_ERR_xx code in a/x.
645
646 SER_UNINSTALL:
647         pushall
648         print_string "SER_UNINSTALL called"
649         pullall
650         jmp     SER_CLOSE
651
652
653 .macro print_string2 addr, len
654         ldx     #0              ; channel 0
655         lda     #<addr
656         sta     ICBAL,x         ; address
657         lda     #>addr
658         sta     ICBAH,x
659         lda     #<len
660         sta     ICBLL,x         ; length
661         lda     #>len
662         sta     ICBLH,x
663         lda     #PUTCHR
664         sta     ICCOM,x
665         jsr     CIOV
666 .endmacro
667
668 .macro  push_ptr1
669         lda     ptr1+1
670         pha
671         lda     ptr1
672         pha
673 .endmacro
674
675 .macro  pull_ptr1
676         pla
677         sta     ptr1
678         pla
679         sta     ptr1+1
680 .endmacro
681
682 .macro  push_ptr2und1
683         lda     ptr2+1
684         pha
685         lda     ptr2
686         pha
687         lda     ptr1+1
688         pha
689         sta     ptr2+1
690         tax
691         lda     ptr1
692         pha
693         sta     ptr2
694 .endmacro
695
696 .macro  pull_ptr2und1
697         pla
698         sta     ptr1
699         pla
700         sta     ptr1+1
701         pla
702         sta     ptr2
703         pla
704         sta     ptr2+1
705 .endmacro
706
707
708 nl_txt:  .byte   ATEOL
709 nl_txt_len = * - nl_txt
710
711 nl:     pushall
712         print_string2 nl_txt, nl_txt_len
713         pullall
714         rts
715
716 iocb_txt:  .byte   " IOCB number: " 
717 iocb_txt_len = * - iocb_txt
718
719 print_iocb_txt:
720         pushall
721         print_string2 iocb_txt, iocb_txt_len
722         pullall
723         rts
724
725 open_txt:  .byte   "OPEN" 
726 open_txt_len = * - open_txt
727
728 print_open_txt:
729         pushall
730         print_string2 open_txt, open_txt_len
731         pullall
732         rts
733
734
735 put_txt:  .byte   "PUT " 
736 put_txt_len = * - put_txt
737
738 print_put_txt:
739         pushall
740         print_string2 put_txt, put_txt_len
741         pullall
742         rts
743
744 aux1_txt:  .byte   "AUX1: " 
745 aux1_txt_len = * - aux1_txt
746
747 dump_aux1:
748         pushall
749         print_string2 aux1_txt,aux1_txt_len
750         tsx
751         lda     $103,x
752         jsr     dump_hex_low
753         jsr     nl
754         pullall
755         rts
756
757 dump_iocb_num:
758         pushall
759         txa
760         jsr     dump_hex_low
761         pullall
762         rts
763
764 dump_hex:
765         pushall
766         tsx
767         lda     $103,x
768         jsr     dump_hex_low
769         pullall
770         rts
771
772
773 ; no need to preserve regs
774 dump_hex_low:
775         tax
776         push_ptr1
777
778         lda     #<outbuf
779         sta     ptr1
780         lda     #>outbuf
781         sta     ptr1+1
782
783         txa
784         jsr     hex8
785
786         ldx     #0              ; channel 0
787
788         lda     #2
789         sta     ICBLL,x         ; length
790         lda     #0
791         sta     ICBLH,x
792
793         lda     #<outbuf
794         sta     ICBAL,x         ; address
795         lda     #>outbuf
796         sta     ICBAH,x
797         lda     #PUTCHR
798         sta     ICCOM,x
799         jsr     CIOV
800
801
802         pull_ptr1
803         rts
804
805
806 ;       ldy     #SER_PARAMS::BAUDRATE
807 ;       lda     (ptr1),y
808
809 dump:
810         pushall
811         push_ptr2und1
812
813 .ifndef __ATARIXL__
814         tay
815         lda     #<outbuf
816         sta     ptr1
817         lda     #>outbuf
818         sta     ptr1+1
819
820         ; ptr1 - pointer to string buffer
821         ; ptr2 - pointer to rs232 params
822         tya
823         jsr     hex16
824         lda     #':'
825         sta     (ptr1),y
826         iny
827         lda     #' '
828         sta     (ptr1),y
829         iny
830         lda     #' '
831         sta     (ptr1),y
832         lda     ptr1
833         clc
834         adc     #3
835         sta     ptr1
836         bcc     @f
837         inc     ptr1+1
838 @f:
839
840 .repeat 5
841
842         ldy     #0
843         lda     (ptr2),y
844         jsr     hex8
845         lda     #' '
846         sta     (ptr1),y
847         inc     ptr1
848         bne     *+4
849         inc     ptr1+1
850         inc     ptr2
851         bne     *+4
852         inc     ptr2+1
853
854 .endrepeat
855
856         lda     #ATEOL
857         sta     (ptr1),y
858         inc     ptr1
859         bne     *+4
860         inc     ptr1+1
861
862         ldx     #0              ; channel 0
863
864         lda     ptr1
865         sec
866         sbc     #<outbuf
867         sta     ICBLL,x         ; length
868         lda     ptr1+1
869         sbc     #>outbuf
870         sta     ICBLH,x
871
872         lda     #<outbuf
873         sta     ICBAL,x         ; address
874         lda     #>outbuf
875         sta     ICBAH,x
876         lda     #PUTCHR
877         sta     ICCOM,x
878         jsr     CIOV
879 .endif
880
881         pull_ptr2und1
882         pullall
883         rts
884
885
886 ; enable concurrent rs232 mode
887 ; gets iocb index in X
888 ; all registers destroyed
889
890 .proc   ena_cm
891
892         lda     #40             ; XIO 40, start concurrent IO
893         sta     ICCOM,x
894         sta     cm_run          ; indicate concurrent mode is running
895         lda     #0
896         sta     ICAX1,x
897         sta     ICAX2,x
898         lda     #<recv_buf
899         sta     ICBAL,x
900         lda     #>recv_buf
901         sta     ICBAH,x
902         lda     #<RECVBUF_SZ
903         sta     ICBLL,x
904         lda     #>RECVBUF_SZ
905         sta     ICBLH,x
906         lda     #$0D            ; value from 850 man, p62.  must be $0D?,
907         sta     ICAX1,x         ;  or any non-zero?
908         jmp     my_CIOV
909
910 .endproc        ;ena_cm
911
912 ;*****************************************************************************
913 ;* Unterprogramm:       HEX16                                                *
914 ;* Aufgabe:             16-bit Binärzahl in String wandeln (hexadezimal)     *
915 ;* Übergabe:            ptr1   - Zeiger auf 4-byte Zielpuffer                *
916 ;*                      AX     - zu wandelnde Zahl (high X, low A)           *
917 ;* Zurück:              ptr1   - Zeiger hinter Hexstring                     *
918 ;*                      Y      - 0                                           *
919 ;* Benutzt:             HEX8                                                 *
920 ;*                                                                           *
921 ;* alle Register zerstört                                                    *
922 ;*****************************************************************************
923
924 hex16:
925         pha
926         txa
927         jsr     hex8
928         pla
929         ;fall into hex8
930
931
932 ;*****************************************************************************
933 ;* Unterprogramm:       HEX8                                                 *
934 ;* Aufgabe:             8-bit Binärzahl in String wandeln (hexadezimal)      *
935 ;* Übergabe:            ptr1   - Zeiger auf 2-byte Zielpuffer                *
936 ;*                      A      - zu wandelnde Zahl                           *
937 ;* Zurück:              ptr1   - Zeiger hinter Hexstring                     *
938 ;*                      Y      - 0                                           *
939 ;*                                                                           *
940 ;* alle Register zerstört                                                    *
941 ;*****************************************************************************
942
943 hex8:
944         tax
945         lsr     a
946         lsr     a
947         lsr     a
948         lsr     a
949         cmp     #10
950         bcc     hex_1
951         clc
952         adc     #'A'-10
953         bne     hex_2
954
955 hex_1:  adc     #'0'
956 hex_2:  ldy     #0
957         sta     (ptr1),y
958         inc     ptr1
959         bne     hex_3
960         inc     ptr1+1
961
962 hex_3:  txa
963         and     #15
964
965         cmp     #10
966         bcc     hex_4
967         clc
968         adc     #'A'-10
969         bne     hex_5
970 hex_4:  adc     #'0'
971 hex_5:  ldy     #0
972         sta     (ptr1),y
973         inc     ptr1
974         bne     hex_6
975         inc     ptr1+1
976 hex_6:  rts
977
978 .data
979
980 outbuf: .res    48