whisperer_in_darkness Posted April 9, 2017 Share Posted April 9, 2017 I found a book with BASIC graphics subroutines in assembler but I'm unable to get the "GRAFIC" subroutine to work. I'm at loss why exactly. The book is Assembly Language Programming For the Atari Computers. I'm using WUDSN, MADS, and Altirra. Below are the subroutines. I'm calling it just by loading a value into accumulator and then jsr grafic, which results in just a blue screen when i run it. No change in graphics mode. The last row was originally: NAME .BYTE "S:",$9B . Perhaps that has got something to do with it? Any help would be much appreciated. ; ****************************** ; CIO equates ; ****************************** ICHID = $0340 ICDNO = $0341 ICCOM = $0342 ICSTA = $0343 ICBAL = $0344 ICBAH = $0345 ICPTL = $0346 ICPTH = $0347 ICBLL = $0348 ICBLH = $0349 ICAX1 = $034A ICAX2 = $034B CIOV = $E456 ; ****************************** ; Other equates needed ; ****************************** COLOR0 = $02C4 COLCRS = $55 ROWCRS = $54 ATACHR = $02FB STORE1 = $CC STOCOL = $CD *= $600 ; ****************************** ; The SETCOLOR routine ; ****************************** ; Before calling this routine, ; the registers should be set ; just like the BASIC SETCOLOR: ; SETCOLOR color,hue,luminance ; stored respectively in ; X reg.,accumulator,Y reg. SETCOL ASL ; Need to multiply ASL ; hue by 16, and ASL ; add it to lumimance. ASL ; Now hue is * 16 STA STORE1 ; temporarily TYA ; So we can add CLC ; Before adding ADC STORE1 ; Now have sum STA COLOR0,X ; Actual SETCOLOR RTS ; All done ; ****************************** ; The COLOR command ; ****************************** ; For these routines, we will ; simply store the current COLOR ; in STOCOL, so the COLOR ; command simply requires that ; the accumulator hold the value ; "n" in the command COLOR n COLOR STA STOCOL ; That's it! RTS ; All done ; ****************************** ; The GRAPHICS command ; ****************************** ; The "n" parameter of ; a GRAPHICS n command will be ; passed to this routine in the ; accumulator GRAFIC PHA ; Store on stack LDX #$60 ; IOCB6 for screen LDA #$C ; CLOSE command STA ICCOM,X ; in command byte JSR CIOV ; Do the CLOSE LDX #$60 ; The screen again LDA #3 ; OPEN command STA ICCOM,X ; in command byte LDA #NAME&255 ; Name is "S:" STA ICBAL,X ; Low byte LDA #NAME/256 ; High byte STA ICBAH,X PLA ; Get GRAPHICS n STA ICAX2,X ; Graphics mode AND #$F0 ; Get high 4 bits EOR #$10 ; Flip high bit ORA #$C ; Read or write STA ICAX1,X ; n+16, n+32 etc. JSR CIOV ; Setup GRAPHICS n RTS ; All done ; ****************************** ; The POSITION command ; ****************************** ; Identical to the BASIC ; POSITION X,Y command. ; Since X may be greater than ; 255 in GRAPHICS 8, we need to ; use the accumulator for the ; high byte of X. POSITN STX COLCRS ; Low byte of X STA COLCRS+1 ; High byte of X STY ROWCRS ; Y position RTS ; All done ; ****************************** ; The PLOT command ; ****************************** ; We'll use the X,Y, and A just ; like in the POSITION command. PLOT JSR POSITN ; To store info LDX #$60 ; For the screen LDA #$B ; Put record STA ICCOM,X ; Command byte LDA #0 ; Special case of STA ICBLL,X ; I/O using the STA ICBLH,X ; accumulator LDA STOCOL ; Get COLOR to use JSR CIOV ; Plot the point RTS ; All done ; ****************************** ; The DRAWTO command ; ****************************** ; We'll use the X,Y, and A just ; like in the POSITION command DRAWTO JSR POSITN ; To store info LDA STOCOL ; Get COLOR STA ATACHR ; Keep CIO happy LDX #$60 ; The screen again LDA #$11 ; For DRAWTO STA ICCOM,X ; Command byte LDA #$C ; As in XIO STA ICAX1,X ; Auxiliary 1 LDA #0 ; Clear STA ICAX2,X ; Auxiliary 2 JSR CIOV ; Draw the line RTS ; All done ; ****************************** ; The FILL command ; ****************************** ; We'll use the X,Y, and A just ; like in the POSITION command. ; This is similar to DRAWTO FILL JSR POSITN ; To store info LDA STOCOL ; Get COLOR STA ATACHR ; Keep CIO happy LDX #$60 ; The screen again LDA #$12 ; For FILL STA ICCOM,X ; Command byte LDA #$C ; As in XIO STA ICAX1,X ; Auxiliary 1 LDA #0 ; Clear STA ICAX2,X ; Auxiliary 2 JSR CIOV ; FILL the area RTS ; All done ; ****************************** ; The LOCATE command ; ****************************** ; We'll use the X,Y, and A just ; like in the POSITION command ; and the accumulator will ; contain the LOCATEd color LOCATE JSR POSITN ; To store info LDX #$60 ; The screen again LDA #7 ; Get record STA ICCOM,X ; Command byte LDA #0 ; Special case of STA ICBLL,X ; data transfer STA ICBLH,X ; in accumulator JSR CIOV ; Do the LOCATE RTS ; All done ; ****************************** ; The screen's name ; ****************************** NAME dta d "S:",$9B Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 9, 2017 Share Posted April 9, 2017 (edited) That last line should be OK - for the CIO Open command you just need the device prefix and Return $9B code as a minimum. By the looks these routines are just building blocks and you need to call them with appropriate parameters. Like the GRAFIC sub - it expects A to contain the graphcis mode so you'd want to make sure to call it as such (try 15 as a test to get Gr. 15) Also note - if you use fullscreen graphics modes (no text window), this can have implications if you're using Basic or in fact probably most other language processor environments. Once the program finishes there will be output to device #0 E: which will override the graphics mode that's been setup and open a new text screen. The GRAFIC sub appears to process the mode the same way Basic does, ie +16 requests no text window. A good way to deal with this is don't let the program just end, do something like a line that waits for key input of just does a GOTO itself and use Break to end the program. Edited April 9, 2017 by Rybags 1 Quote Link to comment Share on other sites More sharing options...
whisperer_in_darkness Posted April 10, 2017 Author Share Posted April 10, 2017 (edited) Thank you for your input Rybags. I am actually calling them with appropriate parameters. This snippet only includes the subroutines. My test program actually only sets a value for A and calls for GRAFIC subroutine and then loops infinitely. I did check that it actually goes through the routine. I have seen two very similar versions of these same subroutines and I have been unable to set graphics mode with either of them for some reason. I'm sure there's a better way to do all this, I'm just curious why it wouldn't work. The fact that these books sometimes have typos in code snippets doesn't really help my paranoia . Edited April 10, 2017 by whisperer_in_darkness Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 10, 2017 Share Posted April 10, 2017 I suspect there might be problems in the source code. Look specifically at instructions where they're trying to use the high or low portion of a 16-bit value. The old way with Atari's AsmEd was like: LDA #LABEL&255 or LDA #LABEL/256 With the more modern assemblers, even Mac-65 the preferred method is: LDA #<LABEL or LDA #>LABEL Also it's worthwhile using debug in the emuator to scroll through the code when it's loaded into Ram - check that what was assembled matches what it should actually be. Not much effort for short routines like these. Quote Link to comment Share on other sites More sharing options...
whisperer_in_darkness Posted April 11, 2017 Author Share Posted April 11, 2017 (edited) I think I got it. I installed another assembler where the correct syntax is: NAME .BYTE "S:",$9B And the code definitely works! I then had a look at MADS documentation and there are in fact two DTA string data types: c ATASCII string, delimited by '' or ""; * at the end encodes inverse video, e.g. dta c'abecadlo'* d INTERNAL string, delimited by '' or ""; * at the end encodes inverse video, e.g. dta d'abecadlo'* Looks like it needs to be ATASCII string like this: dta c "S:",$9B I'm not exactly sure when to use internal and when ATASCII but I guess I'll have to look it up. Edited April 11, 2017 by whisperer_in_darkness Quote Link to comment Share on other sites More sharing options...
Rybags Posted April 11, 2017 Share Posted April 11, 2017 Internal = screen codes, generally you only use that if storing characters directly to screen memory or indexing into a character set e.g. redefining. Internal codes are different so that Gr. 1 and 2 which only have 64 characters could have alpha and numeric within the same charset. 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.